dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
@ 2021-05-14 11:02 dillon.minfei
  2021-05-14 11:02 ` [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver dillon.minfei
                   ` (5 more replies)
  0 siblings, 6 replies; 20+ messages in thread
From: dillon.minfei @ 2021-05-14 11:02 UTC (permalink / raw)
  To: patrice.chotard, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, Dillon Min, linux-stm32, linux-arm-kernel,
	linux-media

From: Dillon Min <dillon.minfei@gmail.com>

This seriese fix three i2c/clk bug for stm32 f4/f7
- kernel runing in sdram, i2c driver get data timeout
- ltdc clk turn off after kernel console active
- kernel hang in set ltdc clock rate

clk bug found on stm32f429/f469-disco board

Hi Patrice:
below is the guide to verify the patch:

setup test env with following files(link at below 'files link'):
[1] u-boot-dtb.bin
[2] rootfs zip file (used in kernel initramfs)
[3] u-boot's mkimage to create itb file
[4] kernel config file
[5] my itb with-or-without i2c patch

This patch based on kernel commit:
88b06399c9c766c283e070b022b5ceafa4f63f19

Note:
panel-ilitek-ili9341.c is the driver which was submitted last year, but not
get accepted. it's used to setup touch screen calibration, then test i2c.

create itb file(please correct path of 'data'):
./mkimage -f stm32.its stm32.itb

HW setup:
console:
       PA9, PA10
       usart0
       serial@40011000
       115200 8n1

-- flash u-boot.bin to stm32f429-disco on PC
$ sudo openocd -f board/stm32f429discovery.cfg -c \
  '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'

-- setup kernel load bootargs at u-boot
U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
                    root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
U-Boot > loady;bootm
(download stm32.dtb or your kernel with itb format, or download zImage, dtb)

-- setup ts_calibrate running env on stm32f429-disco
/ # export TSLIB_CONFFILE=/etc/ts.conf
/ # export TSLIB_TSDEVICE=/dev/input/event0
/ # export TSLIB_CONSOLEDEVICE=none
/ # export TSLIB_FBDEVICE=/dev/fb0

-- clear screen
/ # ./fb

-- run ts_calibrate 
/ # ts_calibrate
(you can calibrate touchscreen now, and get below errors)

[  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
[  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
[  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
[  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16

...
with i2c patch applied, you will find below logs:

RAW---------------------> 3164 908 183 118.110884
TS_READ_RAW----> x = 3164, y =908, pressure = 183
RAW---------------------> 3166 922 126 118.138946
TS_READ_RAW----> x = 3166, y = 922, pressure = 126
....

files link:
https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing




Dillon Min (4):
  drm/panel: Add ilitek ili9341 panel driver
  i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
  clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
  clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
    kernel startup

 drivers/clk/clk-stm32f4.c                    |   10 +-
 drivers/gpu/drm/panel/Kconfig                |   12 +
 drivers/gpu/drm/panel/Makefile               |    1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
 5 files changed, 1310 insertions(+), 10 deletions(-)
 create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver
  2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
@ 2021-05-14 11:02 ` dillon.minfei
  2021-05-31 13:15   ` Patrice CHOTARD
  2021-05-14 11:02 ` [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue dillon.minfei
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: dillon.minfei @ 2021-05-14 11:02 UTC (permalink / raw)
  To: patrice.chotard, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, Dillon Min, linux-stm32, linux-arm-kernel,
	linux-media

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 43057 bytes --]

From: Dillon Min <dillon.minfei@gmail.com>

This driver combine tiny/ili9341.c mipi_dbi_interface driver
with mipi_dpi_interface driver, can support ili9341 with serial
mode or parallel rgb interface mode by register configuration.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/lkml/1590378348-8115-7-git-send-email-dillon.minfei@gmail.com/
Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
---
 drivers/gpu/drm/panel/Kconfig                |   12 +
 drivers/gpu/drm/panel/Makefile               |    1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
 3 files changed, 1298 insertions(+)
 create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4894913936e9..e4babba17864 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -123,6 +123,18 @@ config DRM_PANEL_ILITEK_IL9322
 	  Say Y here if you want to enable support for Ilitek IL9322
 	  QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
 
+config DRM_PANEL_ILITEK_ILI9341
+	tristate "Ilitek ILI9341 240x320 QVGA panels"
+	depends on OF && SPI
+	depends on DRM_KMS_HELPER
+	depends on DRM_KMS_CMA_HELPER
+	depends on BACKLIGHT_CLASS_DEVICE
+	select DRM_MIPI_DBI
+	help
+	  Say Y here if you want to enable support for Ilitek IL9341
+	  QVGA (240x320) RGB panels. support serial & parallel rgb
+	  interface.
+
 config DRM_PANEL_ILITEK_ILI9881C
 	tristate "Ilitek ILI9881C-based panels"
 	depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index cae4d976c069..0ecde184665d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
 obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
 obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
new file mode 100644
index 000000000000..f84983cbb250
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -0,0 +1,1285 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Ilitek ILI9341 TFT LCD drm_panel driver.
+ *
+ * This panel can be configured to support:
+ * - 16-bit parallel RGB interface
+ * - 18-bit parallel RGB interface
+ * - 4-line serial spi interface
+ *
+ * Copyright (C) 2020 Dillon Min <dillon.minfei@gmail.com>
+ * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include <video/mipi_display.h>
+#include <drm/drm_mipi_dbi.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_atomic_helper.h>
+
+#include <drm/drm_drv.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+
+#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
+#define ILI9341_FRC            0xb1   /* Frame Rate Control register */
+#define ILI9341_DFC            0xb6   /* Display Function Control register */
+#define ILI9341_POWER1         0xc0   /* Power Control 1 register */
+#define ILI9341_POWER2         0xc1   /* Power Control 2 register */
+#define ILI9341_VCOM1          0xc5   /* VCOM Control 1 register */
+#define ILI9341_VCOM2          0xc7   /* VCOM Control 2 register */
+#define ILI9341_POWERA         0xcb   /* Power control A register */
+#define ILI9341_POWERB         0xcf   /* Power control B register */
+#define ILI9341_PGAMMA         0xe0   /* Positive Gamma Correction register */
+#define ILI9341_NGAMMA         0xe1   /* Negative Gamma Correction register */
+#define ILI9341_DTCA           0xe8   /* Driver timing control A */
+#define ILI9341_DTCB           0xea   /* Driver timing control B */
+#define ILI9341_POWER_SEQ      0xed   /* Power on sequence register */
+#define ILI9341_3GAMMA_EN      0xf2   /* 3 Gamma enable register */
+#define ILI9341_INTERFACE      0xf6   /* Interface control register */
+#define ILI9341_PRC            0xf7   /* Pump ratio control register */
+#define ILI9341_ETMOD	       0xb7   /* Entry mode set */
+
+#define ILI9341_MADCTL_BGR	BIT(3)
+#define ILI9341_MADCTL_MV	BIT(5)
+#define ILI9341_MADCTL_MX	BIT(6)
+#define ILI9341_MADCTL_MY	BIT(7)
+
+
+#define ILI9341_POWER_B_LEN	3
+#define ILI9341_POWER_SEQ_LEN	4
+#define ILI9341_DTCA_LEN	3
+#define ILI9341_DTCB_LEN	2
+#define ILI9341_POWER_A_LEN	5
+#define ILI9341_DFC_1_LEN	2
+#define ILI9341_FRC_LEN		2
+#define ILI9341_VCOM_1_LEN	2
+#define ILI9341_DFC_2_LEN	4
+#define ILI9341_COLUMN_ADDR_LEN	4
+#define ILI9341_PAGE_ADDR_LEN	4
+#define ILI9341_INTERFACE_LEN	3
+#define ILI9341_PGAMMA_LEN	15
+#define ILI9341_NGAMMA_LEN	15
+#define ILI9341_CA_LEN		3
+
+#define ILI9341_PIXEL_DPI_16_BITS	(BIT(6)|BIT(4))
+#define ILI9341_PIXEL_DPI_18_BITS	(BIT(6)|BIT(5))
+#define ILI9341_GAMMA_CURVE_1		BIT(0)
+#define ILI9341_IF_WE_MODE		BIT(0)
+#define ILI9341_IF_BIG_ENDIAN		0x00
+#define ILI9341_IF_DM_RGB		BIT(2)
+#define ILI9341_IF_DM_INTERNAL		0x00
+#define ILI9341_IF_DM_VSYNC		BIT(3)
+#define ILI9341_IF_RM_RGB		BIT(1)
+#define ILI9341_IF_RIM_RGB		0x00
+
+#define ILI9341_COLUMN_ADDR		0x00ef
+#define ILI9341_PAGE_ADDR		0x013f
+
+#define ILI9341_RGB_EPL			BIT(0)
+#define ILI9341_RGB_DPL			BIT(1)
+#define ILI9341_RGB_HSPL		BIT(2)
+#define ILI9341_RGB_VSPL		BIT(3)
+#define ILI9341_RGB_DE_MODE		BIT(6)
+#define ILI9341_RGB_DISP_PATH_MEM	BIT(7)
+
+#define ILI9341_DBI_VCOMH_4P6V		0x23
+#define ILI9341_DBI_PWR_2_DEFAULT	0x10
+#define ILI9341_DBI_PRC_NORMAL		0x20
+#define ILI9341_DBI_VCOM_1_VMH_4P25V	0x3e
+#define ILI9341_DBI_VCOM_1_VML_1P5V	0x28
+#define ILI9341_DBI_VCOM_2_DEC_58	0x86
+#define ILI9341_DBI_FRC_DIVA		0x00
+#define ILI9341_DBI_FRC_RTNA		0x1b
+#define ILI9341_DBI_EMS_GAS		BIT(0)
+#define ILI9341_DBI_EMS_DTS		BIT(1)
+#define ILI9341_DBI_EMS_GON		BIT(2)
+/**
+ * ili9341_command - ili9341 command with optional parameter(s)
+ * @ili: struct ili9341
+ * @cmd: Command
+ * @seq...: Optional parameter(s)
+ *
+ * Send command to the controller.
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+#define ili9341_command(ili, cmd, seq...) \
+({ \
+	u8 d[] = { seq }; \
+	_ili9341_command(ili, cmd, d, ARRAY_SIZE(d)); \
+})
+
+/**
+ * struct ili9341_config - the system specific ILI9341 configuration
+ * @max_spi_speed: 10000000
+ */
+struct ili9341_config {
+	u32 max_spi_speed;
+	/** @mode: the drm display mode */
+	const struct drm_display_mode mode;
+	/** @ca: TODO: need comments for this register */
+	u8 ca[ILI9341_CA_LEN];
+	/** @power_b: TODO: need comments for this register */
+	u8 power_b[ILI9341_POWER_B_LEN];
+	/** @power_seq: TODO: need comments for this register */
+	u8 power_seq[ILI9341_POWER_SEQ_LEN];
+	/** @dtca: TODO: need comments for this register */
+	u8 dtca[ILI9341_DTCA_LEN];
+	/** @dtcb: TODO: need comments for this register */
+	u8 dtcb[ILI9341_DTCB_LEN];
+	/** @power_a: TODO: need comments for this register */
+	u8 power_a[ILI9341_POWER_A_LEN];
+	/** @frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
+	/*
+	 * Formula to calculate frame frequency:
+	 * Frame Rate=fosc/(Clocks per line x Division ratio x
+	 * (Lines+VBP+VFP))
+	 *
+	 * Sets the division ratio for internal clocks of Normal mode at MCU
+	 * interface.
+	 *
+	 * fosc : internal oscillator frequency
+	 * Clocks per line : RTNA setting
+	 * Division ratio : DIVA setting
+	 * Lines : total driving line number
+	 * VBP : back porch line number
+	 * VFP : front porch line number
+	 *
+	 * RTNA [4:0] Frame Rate (Hz)   RTNA [4:0] Frame Rate (Hz)
+	 * 1 0 0 0 0  119		1 1 0 0 0  79
+	 * 1 0 0 0 1  112		1 1 0 0 1  76
+	 * 1 0 0 1 0  106		1 1 0 1 0  73
+	 * 1 0 0 1 1  100		1 1 0 1 1  70(default)
+	 * 1 0 1 0 0  95		1 1 1 0 0  68
+	 * 1 0 1 0 1  90		1 1 1 0 1  65
+	 * 1 0 1 1 0  86		1 1 1 0 1  63
+	 * 1 0 1 1 1  83		1 1 1 1 1  61
+	 *
+	 * DIVA [1:0] : division ratio for internal clocks when Normal mode.
+	 *
+	 * DIVA [1:0] Division Ratio
+	 * 0 0 fosc
+	 * 0 1 fosc / 2
+	 * 1 0 fosc / 4
+	 * 1 1 fosc / 8
+	 *
+	 */
+	u8 frc[ILI9341_FRC_LEN];
+	/** @prc: TODO: need comments for this register */
+	u8 prc;
+	/** @dfc_1: B6h DISCTRL (Display Function Control) */
+	/*               D/CX RDX WRX D17-8 D7  D6 D5 D4 D3   D2  D1  D0  HEX
+	 * Command       0    1   M   XX    1   0  1  1  0    1   1   0   B6h
+	 * 1st Parameter 1    1   M   XX    0   0  0  0  PTG[1:0] PT[1:0] 0A
+	 * 2nd Parameter 1    1   M   XX    REV GS SS SM ISC[3:0]         82
+	 * 3rd Parameter 1    1   M   XX    0   0  NL[5:0]                27
+	 * 4th Parameter 1    1   M   XX    0   0  PCDIV[5:0]             XX
+	 *
+	 * PTG [1:0]: Set the scan mode in non-display area.
+	 * PTG1 | PTG0 | Gate outputs in   | Source outputs in  | VCOM output
+	 *               non-display area  | non-display area   |
+	 * 1      0      Interval scan       Set with the PT[2:0] bits
+	 *
+	 * PT [1:0]: Determine source/VCOM output in a non-display area in the
+	 * partial display mode.
+	 * 1    0    AGND       AGND       AGND         AGND
+	 *
+	 * REV: Select whether the liquid crystal type is normally white type
+	 * or normally black type.
+	 * REV   Liquid crystal type
+	 * 0     Normally black
+	 * 1     Normally white
+	 *
+	 * SS: Select the shift direction of outputs from the source driver.
+	 * SS    Source Output Scan Direction
+	 * 0     S1 -> S720
+	 * 1     S720 -> S1
+	 *
+	 * GS: Sets the direction of scan by the gate driver in the range
+	 * determined by SCN [4:0] and NL [4:0]. The scan direction
+	 * determined by GS = 0 can be reversed by setting GS = 1.
+	 *
+	 * GS     Gate Output Scan Direction
+	 * 0      G1 -> G320
+	 * 1      G320 -> G1
+	 */
+	u8 dfc_1[ILI9341_DFC_1_LEN];
+	 /** @power_1: Power Control 1 (C0h) */
+	 /* VRH [5:0]: Set the GVDD level, which is a reference level for the
+	 * VCOM level and the grayscale voltage level.
+	 *
+	 * VRH[5:0]    GVDD			VRH[5:0]	GVDD
+	 * 0 0 0 0 0 0 Setting prohibited	1 0 0 0 0 0	4.45 V
+	 * 0 0 0 0 0 1 Setting prohibited	1 0 0 0 0 1	4.50 V
+	 * 0 0 0 0 1 0 Setting prohibited	1 0 0 0 1 0	4.55 V
+	 * 0 0 0 0 1 1 3.00 V			1 0 0 0 1 1	4.60 V
+	 * 0 0 0 1 0 0 3.05 V			1 0 0 1 0 0	4.65 V
+	 * 0 0 0 1 0 1 3.10 V			1 0 0 1 0 1	4.70 V
+	 * 0 0 0 1 1 0 3.15 V			1 0 0 1 1 0	4.75 V
+	 * 0 0 0 1 1 1 3.20 V			1 0 0 1 1 1	4.80 V
+	 * 0 0 1 0 0 0 3.25 V			1 0 1 0 0 0	4.85 V
+	 * 0 0 1 0 0 1 3.30 V			1 0 1 0 0 1	4.90 V
+	 * 0 0 1 0 1 0 3.35 V			1 0 1 0 1 0	4.95 V
+	 * 0 0 1 0 1 1 3.40 V			1 0 1 0 1 1	5.00 V
+	 * 0 0 1 1 0 0 3.45 V			1 0 1 1 0 0	5.05 V
+	 * 0 0 1 1 0 1 3.50 V			1 0 1 1 0 1	5.10 V
+	 * 0 0 1 1 1 0 3.55 V			1 0 1 1 1 0	5.15 V
+	 * 0 0 1 1 1 1 3.60 V			1 0 1 1 1 1	5.20 V
+	 * 0 1 0 0 0 0 3.65 V			1 1 0 0 0 0	5.25 V
+	 * 0 1 0 0 0 1 3.70 V			1 1 0 0 0 1	5.30 V
+	 * 0 1 0 0 1 0 3.75 V			1 1 0 0 1 0	5.35 V
+	 * 0 1 0 0 1 1 3.80 V			1 1 0 0 1 1	5.40 V
+	 * 0 1 0 1 0 0 3.85 V			1 1 0 1 0 0	5.45 V
+	 * 0 1 0 1 0 1 3.90 V			1 1 0 1 0 1	5.50 V
+	 * 0 1 0 1 1 0 3.95 V			1 1 0 1 1 0	5.55 V
+	 * 0 1 0 1 1 1 4.00 V			1 1 0 1 1 1	5.60 V
+	 * 0 1 1 0 0 0 4.05 V			1 1 1 0 0 0	5.65 V
+	 * 0 1 1 0 0 1 4.10 V			1 1 1 0 0 1	5.70 V
+	 * 0 1 1 0 1 0 4.15 V			1 1 1 0 1 0	5.75 V
+	 * 0 1 1 0 1 1 4.20 V			1 1 1 0 1 1	5.80 V
+	 * 0 1 1 1 0 0 4.25 V			1 1 1 1 0 0	5.85 V
+	 * 0 1 1 1 0 1 4.30 V			1 1 1 1 0 1	5.90 V
+	 * 0 1 1 1 1 0 4.35 V			1 1 1 1 1 0	5.95 V
+	 * 0 1 1 1 1 1 4.40 V			1 1 1 1 1 1	6.00 V
+	 */
+	u8 power_1;
+	/** @power_2: Power Control 2 (C1h) */
+	/*
+	 * BT [2:0]: Sets the factor used in the step-up circuits.
+	 * Select the optimal step-up factor for the operating voltage. To
+	 * reduce power consumption, set a smaller factor.
+	 *
+	 * BT[2:0]   AVDD     VGH      VGL
+	 * 0 0 0     VCI x 2  VCI x 7  VCI x 4
+	 * 0 0 1                       VCI x 3
+	 * 0 1 0              VCI x 6  VCI x 4
+	 * 0 1 1		       VCI x 3
+	 *
+	 */
+	u8 power_2;
+	/** @vcom_1: VCOM Control 1(C5h) */
+	/*
+	 * VMH [6:0] : Set the VCOMH voltage
+	 *
+	 * VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH
+	 * 0000000  2.700    0100000  3.500    1000000  4.300    1100000  5.100
+	 * 0000001  2.725    0100001  3.525    1000001  4.325    1100001  5.125
+	 * 0000010  2.750    0100010  3.550    1000010  4.350    1100010  5.150
+	 * 0000011  2.775    0100011  3.575    1000011  4.375    1100011  5.175
+	 * 0000100  2.800    0100100  3.600    1000100  4.400    1100100  5.200
+	 * 0000101  2.825    0100101  3.625    1000101  4.425    1100101  5.225
+	 * 0000110  2.850    0100110  3.650    1000110  4.450    1100110  5.250
+	 * 0000111  2.875    0100111  3.675    1000111  4.475 	 1100111  5.275
+	 * 0001000  2.900    0101000  3.700    1001000  4.500 	 1101000  5.300
+	 * 0001001  2.925    0101001  3.725    1001001  4.525 	 1101001  5.325
+	 * 0001010  2.950    0101010  3.750    1001010  4.550 	 1101010  5.350
+	 * 0001011  2.975    0101011  3.775    1001011  4.575 	 1101011  5.375
+	 * 0001100  3.000    0101100  3.800    1001100  4.600 	 1101100  5.400
+	 * 0001101  3.025    0101101  3.825    1001101  4.625 	 1101101  5.425
+	 * 0001110  3.050    0101110  3.850    1001110  4.650 	 1101110  5.450
+	 * 0001111  3.075    0101111  3.875    1001111  4.675 	 1101111  5.475
+	 * 0010000  3.100    0110000  3.900    1010000  4.700 	 1110000  5.500
+	 * 0010001  3.125    0110001  3.925    1010001  4.725 	 1110001  5.525
+	 * 0010010  3.150    0110010  3.950    1010010  4.750 	 1110010  5.550
+	 * 0010011  3.175    0110011  3.975    1010011  4.775 	 1110011  5.575
+	 * 0010100  3.200    0110100  4.000    1010100  4.800 	 1110100  5.600
+	 * 0010101  3.225    0110101  4.025    1010101  4.825 	 1110101  5.625
+	 * 0010110  3.250    0110110  4.050    1010110  4.850 	 1110110  5.650
+	 * 0010111  3.275    0110111  4.075    1010111  4.875 	 1110111  5.675
+	 * 0011000  3.300    0111000  4.100    1011000  4.900 	 1111000  5.700
+	 * 0011001  3.325    0111001  4.125    1011001  4.925 	 1111001  5.725
+	 * 0011010  3.350    0111010  4.150    1011010  4.950 	 1111010  5.750
+	 * 0011011  3.375    0111011  4.175    1011011  4.975 	 1111011  5.775
+	 * 0011100  3.400    0111100  4.200    1011100  5.000 	 1111100  5.800
+	 * 0011101  3.425    0111101  4.225    1011101  5.025 	 1111101  5.825
+	 * 0011110  3.450    0111110  4.250    1011110  5.050 	 1111110  5.850
+	 * 0011111  3.475    0111111  4.275    1011111  5.075    1111111  5.875
+	 *
+	 * VML[6:0] : Set the VCOML voltage
+	 *
+	 * VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML
+	 * 0000000 -2.500 0100000 -1.700 1000000 -0.900 1100000 -0.100
+	 * 0000001 -2.475 0100001 -1.675 1000001 -0.875 1100001 -0.075
+	 * 0000010 -2.450 0100010 -1.650 1000010 -0.850 1100010 -0.050
+	 * 0000011 -2.425 0100011 -1.625 1000011 -0.825 1100011 -0.025
+	 * 0000100 -2.400 0100100 -1.600 1000100 -0.800 1100100 0
+	 * 0000101 -2.375 0100101 -1.575 1000101 -0.775 1100101 Reserved
+	 * 0000110 -2.350 0100110 -1.550 1000110 -0.750 1100110 Reserved
+	 * 0000111 -2.325 0100111 -1.525 1000111 -0.725 1100111 Reserved
+	 * 0001000 -2.300 0101000 -1.500 1001000 -0.700 1101000 Reserved
+	 * 0001001 -2.275 0101001 -1.475 1001001 -0.675 1101001 Reserved
+	 * 0001010 -2.250 0101010 -1.450 1001010 -0.650 1101010 Reserved
+	 * 0001011 -2.225 0101011 -1.425 1001011 -0.625 1101011 Reserved
+	 * 0001100 -2.200 0101100 -1.400 1001100 -0.600 1101100 Reserved
+	 * 0001101 -2.175 0101101 -1.375 1001101 -0.575 1101101 Reserved
+	 * 0001110 -2.150 0101110 -1.350 1001110 -0.550 1101110 Reserved
+	 * 0001111 -2.125 0101111 -1.325 1001111 -0.525 1101111 Reserved
+	 * 0010000 -2.100 0110000 -1.300 1010000 -0.500 1110000 Reserved
+	 * 0010001 -2.075 0110001 -1.275 1010001 -0.475 1110001 Reserved
+	 * 0010010 -2.050 0110010 -1.250 1010010 -0.450 1110010 Reserved
+	 * 0010011 -2.025 0110011 -1.225 1010011 -0.425 1110011 Reserved
+	 * 0010100 -2.000 0110100 -1.200 1010100 -0.400 1110100 Reserved
+	 * 0010101 -1.975 0110101 -1.175 1010101 -0.375 1110101 Reserved
+	 * 0010110 -1.950 0110110 -1.150 1010110 -0.350 1110110 Reserved
+	 * 0010111 -1.925 0110111 -1.125 1010111 -0.325 1110111 Reserved
+	 * 0011000 -1.900 0111000 -1.100 1011000 -0.300 1111000 Reserved
+	 * 0011001 -1.875 0111001 -1.075 1011001 -0.275 1111001 Reserved
+	 * 0011010 -1.850 0111010 -1.050 1011010 -0.250 1111010 Reserved
+	 * 0011011 -1.825 0111011 -1.025 1011011 -0.225 1111011 Reserved
+	 * 0011100 -1.800 0111100 -1.000 1011100 -0.200 1111100 Reserved
+	 * 0011101 -1.775 0111101 -0.975 1011101 -0.175 1111101 Reserved
+	 * 0011110 -1.750 0111110 -0.950 1011110 -0.150 1111110 Reserved
+	 * 0011111 -1.725 0111111 -0.925 1011111 -0.125 1111111 Reserved
+	 */
+	u8 vcom_1[ILI9341_VCOM_1_LEN];
+	/** @vcom_2: VCOM Control 2(C7h) */
+	/*
+	 * C7h		VMCTRL1 (VCOM Control 1)
+	 *		D/CX RDX WRX D17-8 D7  D6  D5 D4 D3 D2 D1 D0 HEX
+	 * Command 	0    1   M   XX    1   1   0  0  0  1  1  1  C7h
+	 * Parameter 	1    1   M   XX    nVM VMF[6:0]              C0
+	 *
+	 * nVM: nVM equals to “0” after power on reset and VCOM offset
+	 * equals to program MTP value. When nVM set to “1”, setting
+	 * of VMF [6:0] becomes valid and VCOMH/VCOML can be adjusted.
+	 *
+	 * VMF [6:0]: Set the VCOM offset voltage.
+	 */
+	u8 vcom_2;
+	/** @address_mode: Memory Access Control (36h) */
+	/*
+	 * 36h 		MADCTL (Memory Access Control)
+	 * 		D/CX RDX WRX D17-8 D7 D6 D5 D4 D3  D2 D1 D0 HEX
+	 * Command 	0    1   M   XX    0  0  1  1  0   1  1  0  36h
+	 * Parameter 	1    1   M   XX    MY MX MV ML BGR MH 0  0  00
+	 *
+	 * This command defines read/write scanning direction of frame memory.
+	 * This command makes no change on the other driver status.
+	 *
+	 * Bit  Name 			 Description
+	 * MY   Row Address Order
+	 * MX   Column Address Order
+	 * MV 	Row / Column Exchange 	 These 3 bits control MCU to memory
+	 * 				 write/read direction.
+	 * ML 	Vertical Refresh Order 	 LCD vertical refresh direction control.
+	 * BGR 	RGB-BGR Order		 Color selector switch control
+	 *                               (0=RGB color filter panel, 1=BGR
+	 *                               color filter panel)
+	 * MH 	Horizontal Refresh ORDER LCD horizontal refreshing
+	 * direction control.
+	 *
+	 * Note: When BGR bit is changed, the new setting is active
+	 * immediately without update the content in Frame Memory again.
+	 *
+	 */
+	u8 address_mode;
+	/** @g3amma_en: TODO: need comments for this register */
+	u8 g3amma_en;
+	/** @rgb_interface: RGB Interface Signal Control (B0h) */
+	/*
+	 * B0h 		IFMODE (Interface Mode Control)
+	 * 		D/CX RDX WRX D17-8 D7 	       D6     D5     D4 D3   D2   D1  D0  HEX
+	 * Command 	0    1   M   XX    1 	       0      1      1  0    0    0   0   B0h
+	 * Parameter 	1    1   M   XX    ByPass_MODE RCM[1] RCM[0] 0  VSPL HSPL DPL EPL 40
+	 *
+	 * Sets the operation status of the display interface. The setting
+	 * becomes effective as soon as the command is received.
+	 * EPL: DE polarity (“0”= High enable for RGB interface, “1”= Low
+	 * enable for RGB interface)
+	 *
+	 * DPL: DOTCLK polarity set (“0”= data fetched at the rising time,
+	 * “1”= data fetched at the falling time)
+	 *
+	 * HSPL: HSYNC polarity (“0”= Low level sync clock, “1”= High
+	 * level sync clock)
+	 *
+	 * VSPL: VSYNC polarity (“0”= Low level sync clock, “1”= High
+	 * level sync clock)
+	 *
+	 * RCM [1:0]: RGB interface selection (refer to the RGB interface
+	 * section).
+	 *
+	 * ByPass_MODE: Select display data path whether Memory or Direct to
+	 * Shift register when RGB Interface is used.
+	 *
+	 * ByPass_MODE 	Display Data Path
+	 * 0 		Direct to Shift Register (default)
+	 * 1 		Memory
+	 */
+	u8 rgb_interface;
+	/** @dfc_2: refer to dfc_1 */
+	u8 dfc_2[ILI9341_DFC_2_LEN];
+	/** @column_addr: Column Address Set (2Ah) */
+	/* This command is used to define area of frame memory where MCU can
+	 * access. This command makes no change on the
+	 * other driver status. The values of SC [15:0] and EC [15:0] are
+	 * referred when RAMWR command comes. Each value
+	 * represents one column line in the Frame Memory.
+	 */
+	u8 column_addr[ILI9341_COLUMN_ADDR_LEN];
+	/** @page_addr: Page Address Set (2Bh) */
+	/* This command is used to define area of frame memory where MCU can
+	 * access. This command makes no change on the
+	 * other driver status. The values of SP [15:0] and EP [15:0] are
+	 * referred when RAMWR command comes. Each value
+	 * represents one Page line in the Frame Memory.
+	 */
+	u8 page_addr[ILI9341_PAGE_ADDR_LEN];
+	/** @interface: Interface Control (F6h) */
+	/*
+	 * F6h 		IFCTL (16bits Data Format Selection)
+	 * 	        D/CX RDX WRX D17-8 D7   D6   D5     D4     D3      D2     D1     D0      HEX
+	 * Command      0    1   M   XX    1    1    1      1      0       1      1      0       F6h
+	 * 1stParameter 1    1   M   XX    MY   MX   MV
+	 * 				   _EOR _EOR _EOR   0      BGR_EOR 0      0      WE MODE 01
+	 * 2ndParameter 1    1   M   XX    0    0    EPF[1] EPF[0] 0       0      MDT[1] MDT[0]  00
+	 * 3rdParameter 1    1   M   XX    0    0    ENDIAN 0      DM[1]   DM[0]  RM     RIM     00
+	 *
+	 */
+	u8 interface[ILI9341_INTERFACE_LEN];
+	/** @pixel_format: This command sets the pixel format for the RGB image data used by */
+	/* the interface. DPI [2:0] is the pixel format select of RGB
+	 * interface and DBI [2:0] is the pixel format of MCU interface. If a
+	 * particular interface, either RGB interface or MCU interface, is
+	 * not used then the corresponding bits in the parameter are ignored.
+	 * The pixel format is shown in the table below.
+	 *
+	 * DPI[2:0] 	RGB Interface Format 	DBI[2:0] MCU Interface Format
+	 * 0 0 0 	Reserved 		0 0 0 	 Reserved
+	 * 0 0 1 	Reserved 		0 0 1 	 Reserved
+	 * 0 1 0 	Reserved 		0 1 0 	 Reserved
+	 * 0 1 1 	Reserved 		0 1 1 	 Reserved
+	 * 1 0 0 	Reserved 		1 0 0  	 Reserved
+	 * 1 0 1 	16 bits / pixel 	1 0 1    16 bits / pixel
+	 * 1 1 0 	18 bits / pixel 	1 1 0 	 18 bits / pixel
+	 * 1 1 1 	Reserved 		1 1 1 	 Reserved
+	 *
+	 */
+	u8 pixel_format;
+	/** @gamma_curve: This command is used to select the desired Gamma curve for the */
+	/* current display. A maximum of 4 fixed gamma curves can
+	 * be selected. The curve is selected by setting the appropriate bit
+	 * in the parameter as described in the Table:
+	 *
+	 * GC [7:0] 	Curve Selected
+	 * 01h 		Gamma curve 1 (G2.2)
+	 * 02h 		---
+	 * 04h 		---
+	 * 08h 		---
+	 */
+	u8 gamma_curve;
+	/** @pgamma: Positive Gamma Correction (E0h) */
+	/*
+	 * Set the gray scale voltage to adjust the gamma characteristics of
+	 * the TFT panel.
+	 */
+	u8 pgamma[ILI9341_PGAMMA_LEN];
+	/** @ngamma: Negative Gamma Correction (E1h) */
+	/*
+	 * Set the gray scale voltage to adjust the gamma characteristics of
+	 * the TFT panel.
+	 */
+	u8 ngamma[ILI9341_NGAMMA_LEN];
+};
+
+struct ili9341 {
+	struct device *dev;
+	const struct ili9341_config *conf;
+	struct drm_panel panel;
+	struct gpio_desc *reset_gpio;
+	struct gpio_desc *dc_gpio;
+	u32 max_spi_speed;
+	struct regulator *vcc;
+};
+
+/*
+ * The Stm32f429-disco board has a panel ili9341 connected to ltdc controller
+ */
+static const struct ili9341_config ili9341_stm32f429_disco_data = {
+	.max_spi_speed = 10000000,
+	.mode = {
+		.clock = 6100,
+		.hdisplay = 240,
+		.hsync_start = 240 + 10,/* hfp 10 */
+		.hsync_end = 240 + 10 + 10,/* hsync 10 */
+		.htotal = 240 + 10 + 10 + 20,/* hbp 20 */
+		.vdisplay = 320,
+		.vsync_start = 320 + 4,/* vfp 4 */
+		.vsync_end = 320 + 4 + 2,/* vsync 2 */
+		.vtotal = 320 + 4 + 2 + 2,/* vbp 2 */
+		.flags = 0,
+		.width_mm = 65,
+		.height_mm = 50,
+		.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+	},
+	/* TODO: need comments for this register */
+	.ca = {0xc3, 0x08, 0x50},
+	/* TODO: need comments for this register */
+	.power_b = {0x00, 0xc1, 0x30},
+	/* TODO: need comments for this register */
+	.power_seq = {0x64, 0x03, 0x12, 0x81},
+	/* TODO: need comments for this register */
+	.dtca = {0x85, 0x00, 0x78},
+	/* TODO: need comments for this register */
+	.power_a = {0x39, 0x2c, 0x00, 0x34, 0x02},
+	/* TODO: need comments for this register */
+	.prc = 0x20,
+	/* TODO: need comments for this register */
+	.dtcb = {0x00, 0x00},
+	/* 0x00 fosc, 0x1b 70hz */
+	.frc = {0x00, 0x1b},
+	/* 0x0a Interval scan, AGND AGND AGND AGND
+	 * 0xa2 Normally white, G1 -> G320, S720 -> S1,
+	 *	Scan Cycle 5 frames,85ms
+	 */
+	.dfc_1 = {0x0a, 0xa2},
+	/* 0x10 3.65v */
+	.power_1 = 0x10,
+	/* 0x10 AVDD=vci*2, VGH=vci*7, VGL=-vci*4 */
+	.power_2 = 0x10,
+	/* 0x45 VCOMH 4.425v, 0x15 VCOML -1.975*/
+	.vcom_1 = {0x45, 0x15},
+	/* 0x90 offset voltage, VMH-48, VML-48 */
+	.vcom_2 = 0x90,
+	/* 0xc8 Row Address Order, Column Address Order
+	 * 	BGR 1
+	 */
+	.address_mode = 0xc8,
+	.g3amma_en = 0x00,
+	/* 0xc2
+	 * Display Data Path: Memory
+	 * RGB: DE mode
+	 * DOTCLK polarity set (data fetched at the falling time)
+	 */
+	.rgb_interface = ILI9341_RGB_DISP_PATH_MEM |
+			ILI9341_RGB_DE_MODE |
+			ILI9341_RGB_DPL,
+	/*
+	 * 0x0a
+	 * Gate outputs in non-display area: Interval scan
+	 * Determine source/VCOM output in a non-display area in the partial
+	 * display mode: AGND AGND AGND AGND
+	 *
+	 * 0xa7
+	 * Scan Cycle: 15 frames
+	 * fFLM = 60Hz: 255ms
+	 * Liquid crystal type: Normally white
+	 * Gate Output Scan Direction: G1 -> G320
+	 * Source Output Scan Direction: S720 -> S1
+	 *
+	 * 0x27
+	 * LCD Driver Line: 320 lines
+	 *
+	 * 0x04
+	 * PCDIV: 4
+	 */
+	.dfc_2 = {0x0a, 0xa7, 0x27, 0x04},
+	/* column address: 240 */
+	.column_addr = {0x00, 0x00, (ILI9341_COLUMN_ADDR >> 4) & 0xff,
+				ILI9341_COLUMN_ADDR & 0xff},
+	/* page address: 320 */
+	.page_addr = {0x00, 0x00, (ILI9341_PAGE_ADDR >> 4) & 0xff,
+				ILI9341_PAGE_ADDR & 0xff},
+	/* Memory write control: When the transfer number of data exceeds
+	 * (EC-SC+1)*(EP-SP+1), the column and page number will be
+	 * reset, and the exceeding data will be written into the following
+	 * column and page.
+	 * Display Operation Mode: RGB Interface Mode
+	 * Interface for RAM Access: RGB interface
+	 * 16- bit RGB interface (1 transfer/pixel)
+	 */
+	.interface = {ILI9341_IF_WE_MODE, 0x00,
+			ILI9341_IF_DM_RGB | ILI9341_IF_RM_RGB},
+	/* DPI: 16 bits / pixel */
+	.pixel_format = ILI9341_PIXEL_DPI_16_BITS,
+	/* Curve Selected: Gamma curve 1 (G2.2) */
+	.gamma_curve = ILI9341_GAMMA_CURVE_1,
+	.pgamma = {0x0f, 0x29, 0x24, 0x0c, 0x0e,
+			0x09, 0x4e, 0x78, 0x3c, 0x09,
+			0x13, 0x05, 0x17, 0x11, 0x00},
+	.ngamma = {0x00, 0x16, 0x1b, 0x04, 0x11,
+			0x07, 0x31, 0x33, 0x42, 0x05,
+			0x0c, 0x0a, 0x28, 0x2f, 0x0f},
+};
+
+static inline struct ili9341 *panel_to_ili9341(struct drm_panel *panel)
+{
+	return container_of(panel, struct ili9341, panel);
+}
+
+static int ili9341_spi_transfer(struct spi_device *spi, u32 speed_hz,
+			  u8 bpw, const void *buf, size_t len)
+{
+	size_t max_chunk = spi_max_transfer_size(spi);
+	struct spi_transfer tr = {
+		.bits_per_word = bpw,
+		.speed_hz = speed_hz,
+		.len = len,
+	};
+	struct spi_message m;
+	size_t chunk;
+	int ret;
+
+	spi_message_init_with_transfers(&m, &tr, 1);
+
+	while (len) {
+		chunk = min(len, max_chunk);
+
+		tr.tx_buf = buf;
+		tr.len = chunk;
+		buf += chunk;
+		len -= chunk;
+
+		ret = spi_sync(spi, &m);
+		if (ret) {
+			dev_err(&spi->dev, "spi_sync error: %d\n", ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int _ili9341_command(struct ili9341 *ili, u8 cmd, const void *data,
+				    size_t count)
+{
+	struct spi_device *spi = to_spi_device(ili->dev);
+	int ret = 0;
+
+	gpiod_set_value_cansleep(ili->dc_gpio, 0);
+
+	ret = ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
+					(const void *)&cmd, 1);
+	if (ret || data == NULL || count == 0) {
+		return ret;
+	}
+
+	gpiod_set_value_cansleep(ili->dc_gpio, 1);
+
+	return ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
+		data, count);
+}
+
+static int ili9341_dpi_init(struct ili9341 *ili)
+{
+	int ret;
+	ret = _ili9341_command(ili, 0xca,
+			ili->conf->ca,
+			ILI9341_CA_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_POWERB,
+			ili->conf->power_b,
+			ILI9341_POWER_B_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_POWER_SEQ,
+			ili->conf->power_seq,
+			ILI9341_POWER_SEQ_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_DTCA,
+			ili->conf->dtca,
+			ILI9341_DTCA_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_POWERA,
+			ili->conf->power_a,
+			ILI9341_POWER_A_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_PRC,
+			&ili->conf->prc,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_DTCB,
+			ili->conf->dtcb,
+			ILI9341_DTCB_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_FRC,
+			ili->conf->frc,
+			ILI9341_FRC_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_DFC,
+			ili->conf->dfc_1,
+			ILI9341_DFC_1_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_POWER1,
+			&ili->conf->power_1,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_POWER2,
+			&ili->conf->power_2,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_VCOM1,
+			ili->conf->vcom_1,
+			ILI9341_VCOM_1_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_VCOM2,
+			&ili->conf->vcom_2,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, MIPI_DCS_SET_ADDRESS_MODE,
+			&ili->conf->address_mode,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_3GAMMA_EN,
+			&ili->conf->g3amma_en,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_RGB_INTERFACE,
+			&ili->conf->rgb_interface,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_DFC,
+			ili->conf->dfc_2,
+			ILI9341_DFC_2_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, MIPI_DCS_SET_COLUMN_ADDRESS,
+			ili->conf->column_addr,
+			ILI9341_COLUMN_ADDR_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, MIPI_DCS_SET_PAGE_ADDRESS,
+			ili->conf->page_addr,
+			ILI9341_PAGE_ADDR_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_INTERFACE,
+			ili->conf->interface,
+			ILI9341_INTERFACE_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, MIPI_DCS_SET_PIXEL_FORMAT,
+			&ili->conf->pixel_format,
+			1);
+	if (ret)
+		return ret;
+
+	ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
+	if (ret)
+		return ret;
+
+	msleep(200);
+	ret = _ili9341_command(ili, MIPI_DCS_SET_GAMMA_CURVE,
+			&ili->conf->gamma_curve,
+			1);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_PGAMMA,
+			ili->conf->pgamma,
+			ILI9341_PGAMMA_LEN);
+	if (ret)
+		return ret;
+
+	ret = _ili9341_command(ili, ILI9341_NGAMMA,
+			ili->conf->ngamma,
+			ILI9341_NGAMMA_LEN);
+	if (ret)
+		return ret;
+
+	ret = ili9341_command(ili, MIPI_DCS_EXIT_SLEEP_MODE);
+	if (ret)
+		return ret;
+
+	msleep(200);
+	ret = ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
+	if (ret)
+		return ret;
+
+	ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
+	if (ret)
+		return ret;
+
+	dev_info(ili->dev, "initialized display rgb interface\n");
+
+	return 0;
+}
+
+static int ili9341_dpi_power_on(struct ili9341 *ili)
+{
+	int ret = 0;
+
+	/* Assert RESET */
+	gpiod_set_value(ili->reset_gpio, 1);
+
+	/* Enable power */
+	if (!IS_ERR(ili->vcc)) {
+		ret = regulator_enable(ili->vcc);
+		if (ret < 0) {
+			dev_err(ili->dev, "unable to enable vcc\n");
+			return ret;
+		}
+	}
+	msleep(20);
+
+	/* De-assert RESET */
+	gpiod_set_value(ili->reset_gpio, 0);
+	msleep(10);
+
+	return 0;
+}
+
+static int ili9341_dpi_power_off(struct ili9341 *ili)
+{
+	/* Assert RESET */
+	gpiod_set_value(ili->reset_gpio, 1);
+
+	/* Disable power */
+	if (!IS_ERR(ili->vcc))
+		return regulator_disable(ili->vcc);
+
+	return 0;
+}
+
+static int ili9341_dpi_disable(struct drm_panel *panel)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+
+	ili9341_command(ili, MIPI_DCS_SET_DISPLAY_OFF);
+
+	return 0;
+}
+
+static int ili9341_dpi_unprepare(struct drm_panel *panel)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+
+	return ili9341_dpi_power_off(ili);
+}
+
+static int ili9341_dpi_prepare(struct drm_panel *panel)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+	int ret;
+
+	ret = ili9341_dpi_power_on(ili);
+	if (ret < 0)
+		return ret;
+
+	ret = ili9341_dpi_init(ili);
+	if (ret < 0)
+		ili9341_dpi_unprepare(panel);
+
+	return ret;
+}
+
+static int ili9341_dpi_enable(struct drm_panel *panel)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+
+	ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
+
+	return 0;
+}
+
+static int ili9341_dpi_get_modes(struct drm_panel *panel,
+				struct drm_connector *connector)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+	struct drm_device *drm = connector->dev;
+	struct drm_display_mode *mode;
+	struct drm_display_info *info;
+
+	info = &connector->display_info;
+	info->width_mm = ili->conf->mode.width_mm;
+	info->height_mm = ili->conf->mode.height_mm;
+
+	if (ili->conf->rgb_interface & ILI9341_RGB_DPL)
+		info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
+	else
+		info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
+
+	if (ili->conf->rgb_interface & ILI9341_RGB_EPL)
+		info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
+	else
+		info->bus_flags |= DRM_BUS_FLAG_DE_HIGH;
+
+	mode = drm_mode_duplicate(drm, &ili->conf->mode);
+	if (!mode) {
+		DRM_ERROR("bad mode or failed to add mode\n");
+		return -EINVAL;
+	}
+	drm_mode_set_name(mode);
+
+	/* Set up the polarity */
+	if (ili->conf->rgb_interface & ILI9341_RGB_HSPL)
+		mode->flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		mode->flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (ili->conf->rgb_interface & ILI9341_RGB_VSPL)
+		mode->flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		mode->flags |= DRM_MODE_FLAG_NVSYNC;
+
+	drm_mode_probed_add(connector, mode);
+
+	return 1; /* Number of modes */
+}
+
+static const struct drm_panel_funcs ili9341_dpi_funcs = {
+	.disable = ili9341_dpi_disable,
+	.unprepare = ili9341_dpi_unprepare,
+	.prepare = ili9341_dpi_prepare,
+	.enable = ili9341_dpi_enable,
+	.get_modes = ili9341_dpi_get_modes,
+};
+
+static int ili9341_dpi_probe(struct spi_device *spi)
+{
+	int ret;
+	struct device *dev = &spi->dev;
+	struct ili9341 *ili;
+
+	ili = devm_kzalloc(dev, sizeof(struct ili9341), GFP_KERNEL);
+	if (!ili)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, ili);
+
+	ili->dev = dev;
+	/*
+	 * Every new incarnation of this display must have a unique
+	 * data entry for the system in this driver.
+	 */
+	ili->conf = of_device_get_match_data(dev);
+	if (!ili->conf) {
+		dev_err(dev, "missing device configuration\n");
+		return -ENODEV;
+	}
+
+	ili->vcc = devm_regulator_get_optional(dev, "vcc");
+	if (IS_ERR(ili->vcc))
+		dev_err(dev, "get optional vcc failed\n");
+
+	ili->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+		GPIOD_OUT_HIGH);
+	if (IS_ERR(ili->reset_gpio)) {
+		dev_err(dev, "failed to get RESET GPIO\n");
+		return PTR_ERR(ili->reset_gpio);
+	}
+
+	ili->dc_gpio = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
+	if (IS_ERR(ili->dc_gpio)) {
+		dev_err(dev, "failed to get DC GPIO\n");
+		return PTR_ERR(ili->dc_gpio);
+	}
+
+	spi->bits_per_word = 8;
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(dev, "spi setup failed.\n");
+		return ret;
+	}
+
+	ili->max_spi_speed = ili->conf->max_spi_speed;
+
+	drm_panel_init(&ili->panel, dev, &ili9341_dpi_funcs,
+		       DRM_MODE_CONNECTOR_DPI);
+
+	drm_panel_add(&ili->panel);
+
+	return 0;
+}
+
+
+
+static void ili9341_dbi_enable(struct drm_simple_display_pipe *pipe,
+			     struct drm_crtc_state *crtc_state,
+			     struct drm_plane_state *plane_state)
+{
+	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
+	struct mipi_dbi *dbi = &dbidev->dbi;
+	u8 addr_mode;
+	int ret, idx;
+
+	if (!drm_dev_enter(pipe->crtc.dev, &idx))
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+	ret = mipi_dbi_poweron_conditional_reset(dbidev);
+	if (ret < 0)
+		goto out_exit;
+	if (ret == 1)
+		goto out_enable;
+
+	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
+
+	mipi_dbi_command(dbi, ILI9341_POWERB, 0x00, 0xc1, 0x30);
+	mipi_dbi_command(dbi, ILI9341_POWER_SEQ, 0x64, 0x03, 0x12, 0x81);
+	mipi_dbi_command(dbi, ILI9341_DTCA, 0x85, 0x00, 0x78);
+	mipi_dbi_command(dbi, ILI9341_POWERA, 0x39, 0x2c, 0x00, 0x34, 0x02);
+	mipi_dbi_command(dbi, ILI9341_PRC, ILI9341_DBI_PRC_NORMAL);
+	mipi_dbi_command(dbi, ILI9341_DTCB, 0x00, 0x00);
+
+	/* Power Control */
+	mipi_dbi_command(dbi, ILI9341_POWER1, ILI9341_DBI_VCOMH_4P6V);
+	mipi_dbi_command(dbi, ILI9341_POWER2, ILI9341_DBI_PWR_2_DEFAULT);
+	/* VCOM */
+	mipi_dbi_command(dbi, ILI9341_VCOM1, ILI9341_DBI_VCOM_1_VMH_4P25V,
+						ILI9341_DBI_VCOM_1_VML_1P5V);
+	mipi_dbi_command(dbi, ILI9341_VCOM2, ILI9341_DBI_VCOM_2_DEC_58);
+
+	/* Memory Access Control */
+	mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT,
+				MIPI_DCS_PIXEL_FMT_16BIT);
+
+	/* Frame Rate */
+	mipi_dbi_command(dbi, ILI9341_FRC, ILI9341_DBI_FRC_DIVA & 0x03,
+						ILI9341_DBI_FRC_RTNA & 0x1f);
+
+	/* Gamma */
+	mipi_dbi_command(dbi, ILI9341_3GAMMA_EN, 0x00);
+	mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, ILI9341_GAMMA_CURVE_1);
+	mipi_dbi_command(dbi, ILI9341_PGAMMA,
+			 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
+			 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
+	mipi_dbi_command(dbi, ILI9341_NGAMMA,
+			 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
+			 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
+
+	/* DDRAM */
+	mipi_dbi_command(dbi, ILI9341_ETMOD, ILI9341_DBI_EMS_GAS |
+						ILI9341_DBI_EMS_DTS |
+						ILI9341_DBI_EMS_GON);
+
+	/* Display */
+	mipi_dbi_command(dbi, ILI9341_DFC, 0x08, 0x82, 0x27, 0x00);
+	mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
+	msleep(100);
+
+	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
+	msleep(100);
+
+out_enable:
+	switch (dbidev->rotation) {
+	default:
+		addr_mode = ILI9341_MADCTL_MX;
+		break;
+	case 90:
+		addr_mode = ILI9341_MADCTL_MV;
+		break;
+	case 180:
+		addr_mode = ILI9341_MADCTL_MY;
+		break;
+	case 270:
+		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
+			    ILI9341_MADCTL_MX;
+		break;
+	}
+	addr_mode |= ILI9341_MADCTL_BGR;
+	mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+	DRM_DEBUG_KMS("initialized display serial interface\n");
+out_exit:
+	drm_dev_exit(idx);
+}
+
+static const struct drm_simple_display_pipe_funcs ili9341_dbi_funcs = {
+	.enable = ili9341_dbi_enable,
+	.disable = mipi_dbi_pipe_disable,
+	.update = mipi_dbi_pipe_update,
+	.prepare_fb = drm_gem_simple_display_pipe_prepare_fb,
+};
+
+static const struct drm_display_mode ili9341_dbi_mode = {
+	DRM_SIMPLE_MODE(240, 320, 37, 49),
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(ili9341_dbi_fops);
+
+static struct drm_driver ili9341_dbi_driver = {
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+	.fops			= &ili9341_dbi_fops,
+	DRM_GEM_CMA_DRIVER_OPS_VMAP,
+	.debugfs_init		= mipi_dbi_debugfs_init,
+	.name			= "ili9341",
+	.desc			= "Ilitek ILI9341",
+	.date			= "20180514",
+	.major			= 1,
+	.minor			= 0,
+};
+static int ili9341_dbi_probe(struct spi_device *spi)
+{
+	struct mipi_dbi_dev *dbidev;
+	struct drm_device *drm;
+	struct mipi_dbi *dbi;
+	struct gpio_desc *dc;
+	struct device *dev = &spi->dev;
+	u32 rotation = 0;
+	int ret;
+
+	dbidev = devm_drm_dev_alloc(dev, &ili9341_dbi_driver,
+				    struct mipi_dbi_dev, drm);
+	if (IS_ERR(dbidev))
+		return PTR_ERR(dbidev);
+
+	dbi = &dbidev->dbi;
+	drm = &dbidev->drm;
+
+	drm_mode_config_init(drm);
+
+	dbi->reset = devm_gpiod_get_optional(dev, "reset",
+					GPIOD_OUT_HIGH);
+	if (IS_ERR(dbi->reset)) {
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
+		return PTR_ERR(dbi->reset);
+	}
+
+	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
+	if (IS_ERR(dc)) {
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
+		return PTR_ERR(dc);
+	}
+
+	dbidev->regulator = devm_regulator_get_optional(dev, "vcc");
+	if (IS_ERR(dbidev->regulator))
+		dev_err(dev, "get optional vcc failed\n");
+
+	dbidev->backlight = devm_of_find_backlight(dev);
+	if (IS_ERR(dbidev->backlight))
+		return PTR_ERR(dbidev->backlight);
+
+	device_property_read_u32(dev, "rotation", &rotation);
+
+	ret = mipi_dbi_spi_init(spi, dbi, dc);
+	if (ret)
+		return ret;
+
+	ret = mipi_dbi_dev_init(dbidev, &ili9341_dbi_funcs,
+					&ili9341_dbi_mode, rotation);
+	if (ret)
+		return ret;
+
+	drm_mode_config_reset(drm);
+
+	ret = drm_dev_register(drm, 0);
+	if (ret)
+		return ret;
+
+	spi_set_drvdata(spi, drm);
+
+	drm_fbdev_generic_setup(drm, 0);
+
+	return 0;
+}
+static int ili9341_probe(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+
+	if (!strcmp(id->name, "sf-tc240t-9370-t"))
+		return ili9341_dpi_probe(spi);
+	else if (!strcmp(id->name, "yx240qv29"))
+		return ili9341_dbi_probe(spi);
+
+	return -1;
+}
+
+static int ili9341_remove(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+	struct ili9341 *ili = spi_get_drvdata(spi);
+	struct drm_device *drm = spi_get_drvdata(spi);
+
+	if (!strcmp(id->name, "sf-tc240t-9370-t")) {
+		ili9341_dpi_power_off(ili);
+		drm_panel_remove(&ili->panel);
+	} else if (!strcmp(id->name, "yx240qv29")) {
+		drm_dev_unplug(drm);
+		drm_atomic_helper_shutdown(drm);
+	}
+	return 0;
+}
+
+static void ili9341_shutdown(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+
+	if (!strcmp(id->name, "yx240qv29"))
+		drm_atomic_helper_shutdown(spi_get_drvdata(spi));
+}
+
+static const struct of_device_id ili9341_of_match[] = {
+	{
+		.compatible = "st,sf-tc240t-9370-t",
+		.data = &ili9341_stm32f429_disco_data,
+	},
+	{
+		/* porting from tiny/ili9341.c
+		 * for original mipi dbi compitable
+		 */
+		.compatible = "adafruit,yx240qv29",
+		.data = NULL,
+	},
+};
+MODULE_DEVICE_TABLE(of, ili9341_of_match);
+
+static const struct spi_device_id ili9341_id[] = {
+	{ "yx240qv29", 0 },
+	{ "sf-tc240t-9370-t", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, ili9341_id);
+
+static struct spi_driver ili9341_driver = {
+	.probe = ili9341_probe,
+	.remove = ili9341_remove,
+	.shutdown = ili9341_shutdown,
+	.id_table = ili9341_id,
+	.driver = {
+		.name = "panel-ilitek-ili9341",
+		.of_match_table = ili9341_of_match,
+	},
+};
+module_spi_driver(ili9341_driver);
+
+MODULE_AUTHOR("Dillon Min <dillon.minfei@gmail.com>");
+MODULE_DESCRIPTION("ILI9341 LCD panel driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
  2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
  2021-05-14 11:02 ` [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver dillon.minfei
@ 2021-05-14 11:02 ` dillon.minfei
  2021-06-01 11:43   ` Patrice CHOTARD
  2021-05-14 11:02 ` [PATCH 3/4] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate dillon.minfei
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: dillon.minfei @ 2021-05-14 11:02 UTC (permalink / raw)
  To: patrice.chotard, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, Dillon Min, linux-stm32, linux-arm-kernel,
	linux-media

From: Dillon Min <dillon.minfei@gmail.com>

As stm32f429's internal flash is 2Mbytes and compiled kernel
image bigger than 2Mbytes, so we have to load kernel image
to sdram on stm32f429-disco board which has 8Mbytes sdram space.

based on above context, as you knows kernel running on external
sdram is more slower than internal flash. besides, we need read 4
bytes to get touch screen xyz(x, y, pressure) coordinate data in
stmpe811 interrupt.

so, in stm32f4_i2c_handle_rx_done, as i2c read slower than running
in xip mode, have to adjust 'STOP/START bit set position' from last
two bytes to last one bytes. else, will get i2c timeout in reading
touch screen coordinate.

to not bring in side effect, introduce IIC_LAST_BYTE_POS to support xip
kernel or zImage.

Fixes: 62817fc8d282 ("i2c: stm32f4: add driver")
Link: https://lore.kernel.org/lkml/1591709203-12106-5-git-send-email-dillon.minfei@gmail.com/
Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
---
 drivers/i2c/busses/i2c-stm32f4.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
index 4933fc8ce3fd..2e41231b9037 100644
--- a/drivers/i2c/busses/i2c-stm32f4.c
+++ b/drivers/i2c/busses/i2c-stm32f4.c
@@ -93,6 +93,12 @@
 #define STM32F4_I2C_MAX_FREQ		46U
 #define HZ_TO_MHZ			1000000
 
+#if !defined(CONFIG_MMU) && !defined(CONFIG_XIP_KERNEL)
+#define IIC_LAST_BYTE_POS 1
+#else
+#define IIC_LAST_BYTE_POS 2
+#endif
+
 /**
  * struct stm32f4_i2c_msg - client specific data
  * @addr: 8-bit slave addr, including r/w bit
@@ -439,7 +445,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
 	int i;
 
 	switch (msg->count) {
-	case 2:
+	case IIC_LAST_BYTE_POS:
 		/*
 		 * In order to correctly send the Stop or Repeated Start
 		 * condition on the I2C bus, the STOP/START bit has to be set
@@ -454,7 +460,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
 		else
 			stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
 
-		for (i = 2; i > 0; i--)
+		for (i = IIC_LAST_BYTE_POS; i > 0; i--)
 			stm32f4_i2c_read_msg(i2c_dev);
 
 		reg = i2c_dev->base + STM32F4_I2C_CR2;
@@ -463,7 +469,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
 
 		complete(&i2c_dev->complete);
 		break;
-	case 3:
+	case (IIC_LAST_BYTE_POS+1):
 		/*
 		 * In order to correctly generate the NACK pulse after the last
 		 * received data byte, we have to enable NACK before reading N-2
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/4] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
  2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
  2021-05-14 11:02 ` [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver dillon.minfei
  2021-05-14 11:02 ` [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue dillon.minfei
@ 2021-05-14 11:02 ` dillon.minfei
  2021-06-01 12:48   ` Patrice CHOTARD
  2021-05-14 11:02 ` [PATCH 4/4] clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after kernel startup dillon.minfei
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: dillon.minfei @ 2021-05-14 11:02 UTC (permalink / raw)
  To: patrice.chotard, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, Dillon Min, linux-stm32, linux-arm-kernel,
	linux-media

From: Dillon Min <dillon.minfei@gmail.com>

This is due to misuse ‘PLL_VCO_SAI' and'PLL_SAI' in clk-stm32f4.c
'PLL_SAI' is 2, 'PLL_VCO_SAI' is 7(defined in
include/dt-bindings/clock/stm32fx-clock.h).

'post_div' point to 'post_div_data[]', 'post_div->pll_num'
is PLL_I2S or PLL_SAI.

'clks[PLL_VCO_SAI]' has valid 'struct clk_hw* ' return
from stm32f4_rcc_register_pll() but, at line 1777 of
driver/clk/clk-stm32f4.c, use the 'clks[post_div->pll_num]',
equal to 'clks[PLL_SAI]', this is invalid array member at that time.

Fixes: 517633ef630e ("clk: stm32f4: Add post divisor for I2S & SAI PLLs")
Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/linux-arm-kernel/1590564453-24499-6-git-send-email-dillon.minfei@gmail.com/
---
 drivers/clk/clk-stm32f4.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 18117ce5ff85..42ca2dd86aea 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -557,13 +557,13 @@ static const struct clk_div_table post_divr_table[] = {
 
 #define MAX_POST_DIV 3
 static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
-	{ CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
+	{ CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
 		CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
 
-	{ CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
+	{ CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
 		CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
 
-	{ NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
+	{ NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
 		STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
 };
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/4] clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after kernel startup
  2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
                   ` (2 preceding siblings ...)
  2021-05-14 11:02 ` [PATCH 3/4] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate dillon.minfei
@ 2021-05-14 11:02 ` dillon.minfei
  2021-06-01 12:51   ` Patrice CHOTARD
  2021-05-28  6:01 ` [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform Dillon Min
  2021-05-31 13:20 ` Patrice CHOTARD
  5 siblings, 1 reply; 20+ messages in thread
From: dillon.minfei @ 2021-05-14 11:02 UTC (permalink / raw)
  To: patrice.chotard, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, Dillon Min, linux-stm32, linux-arm-kernel,
	linux-media

From: Dillon Min <dillon.minfei@gmail.com>

stm32's clk driver register two ltdc gate clk to clk core by
clk_hw_register_gate() and clk_hw_register_composite()

first: 'stm32f429_gates[]', clk name is 'ltdc', which no user to use.
second: 'stm32f429_aux_clk[]', clk name is 'lcd-tft', used by ltdc driver

both of them point to the same offset of stm32's RCC register. after
kernel enter console, clk core turn off ltdc's clk as 'stm32f429_gates[]'
is no one to use. but, actually 'stm32f429_aux_clk[]' is in use.

Fixes: daf2d117cbca ("clk: stm32f4: Add lcd-tft clock")
Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/linux-arm-kernel/1590564453-24499-7-git-send-email-dillon.minfei@gmail.com/
---
 drivers/clk/clk-stm32f4.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 42ca2dd86aea..f4156a8a6041 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = {
 	{ STM32F4_RCC_APB2ENR, 20,	"spi5",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
-	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
@@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
 	{ STM32F4_RCC_APB2ENR, 20,	"spi5",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
-	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
@@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
 	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 23,	"sai2",		"apb2_div" },
-	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
@@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
 	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 23,	"sai2",		"apb2_div" },
-	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
 	{ STM32F4_RCC_APB2ENR, 30,	"mdio",		"apb2_div" },
 };
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
                   ` (3 preceding siblings ...)
  2021-05-14 11:02 ` [PATCH 4/4] clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after kernel startup dillon.minfei
@ 2021-05-28  6:01 ` Dillon Min
  2021-05-31 13:20 ` Patrice CHOTARD
  5 siblings, 0 replies; 20+ messages in thread
From: Dillon Min @ 2021-05-28  6:01 UTC (permalink / raw)
  To: Patrice CHOTARD, pierre-yves.mordret, alain.volmat,
	Maxime Coquelin, Alexandre TORGUE, Sumit Semwal,
	christian.koenig, Michael Turquette
  Cc: Wolfram Sang, Stephen Boyd, Linux Kernel Mailing List,
	open list:DRM PANEL DRIVERS, linux-clk, linaro-mm-sig, linux-i2c,
	linux-stm32, Linux ARM, linux-media

Hi Patrice, Alain,

Could you help to take a look at this patchset, thanks.

This series is the rebase to the newest kernel commit:
88b06399c9c766c283e070b022b5ceafa4f63f19

according to the request from:
https://lore.kernel.org/lkml/ff2bc09d-1a17-50d4-d3ee-16fd3a86d7f1@foss.st.com/

The clk bug affects the kernel bootup on stm32f469-disco board
in case display config(CONFIG_DRM_STM, CONFIG_DRM_STM_DSI,
DRM_PANEL_ORISETECH_OTM8009A)
enabled.

If you want to test clk patch on stm32f429-disco board, the
panel-ilitek-ili9341.c can be
used for that purpose (CONFIG_DRM_STM, DRM_PANEL_ILITEK_ILI9341)

i2c driver patch intent to fix the touch panel driver get data through
i2c bus timeout issue.

Best regards.
Dillon

On Fri, May 14, 2021 at 7:02 PM <dillon.minfei@gmail.com> wrote:
>
> From: Dillon Min <dillon.minfei@gmail.com>
>
> This seriese fix three i2c/clk bug for stm32 f4/f7
> - kernel runing in sdram, i2c driver get data timeout
> - ltdc clk turn off after kernel console active
> - kernel hang in set ltdc clock rate
>
> clk bug found on stm32f429/f469-disco board
>
> Hi Patrice:
> below is the guide to verify the patch:
>
> setup test env with following files(link at below 'files link'):
> [1] u-boot-dtb.bin
> [2] rootfs zip file (used in kernel initramfs)
> [3] u-boot's mkimage to create itb file
> [4] kernel config file
> [5] my itb with-or-without i2c patch
>
> This patch based on kernel commit:
> 88b06399c9c766c283e070b022b5ceafa4f63f19
>
> Note:
> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
> get accepted. it's used to setup touch screen calibration, then test i2c.
>
> create itb file(please correct path of 'data'):
> ./mkimage -f stm32.its stm32.itb
>
> HW setup:
> console:
>        PA9, PA10
>        usart0
>        serial@40011000
>        115200 8n1
>
> -- flash u-boot.bin to stm32f429-disco on PC
> $ sudo openocd -f board/stm32f429discovery.cfg -c \
>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
>
> -- setup kernel load bootargs at u-boot
> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
> U-Boot > loady;bootm
> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
>
> -- setup ts_calibrate running env on stm32f429-disco
> / # export TSLIB_CONFFILE=/etc/ts.conf
> / # export TSLIB_TSDEVICE=/dev/input/event0
> / # export TSLIB_CONSOLEDEVICE=none
> / # export TSLIB_FBDEVICE=/dev/fb0
>
> -- clear screen
> / # ./fb
>
> -- run ts_calibrate
> / # ts_calibrate
> (you can calibrate touchscreen now, and get below errors)
>
> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
>
> ...
> with i2c patch applied, you will find below logs:
>
> RAW---------------------> 3164 908 183 118.110884
> TS_READ_RAW----> x = 3164, y =908, pressure = 183
> RAW---------------------> 3166 922 126 118.138946
> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
> ....
>
> files link:
> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
>
>
>
>
> Dillon Min (4):
>   drm/panel: Add ilitek ili9341 panel driver
>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
>     kernel startup
>
>  drivers/clk/clk-stm32f4.c                    |   10 +-
>  drivers/gpu/drm/panel/Kconfig                |   12 +
>  drivers/gpu/drm/panel/Makefile               |    1 +
>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
>  5 files changed, 1310 insertions(+), 10 deletions(-)
>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
>
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver
  2021-05-14 11:02 ` [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver dillon.minfei
@ 2021-05-31 13:15   ` Patrice CHOTARD
  2021-05-31 13:39     ` Dillon Min
  0 siblings, 1 reply; 20+ messages in thread
From: Patrice CHOTARD @ 2021-05-31 13:15 UTC (permalink / raw)
  To: dillon.minfei, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, linux-stm32, linux-arm-kernel, linux-media

Hi Dillon

When trying to applying this patch using "git am --3 <patch>"  i got this error :

error: cannot convert from y to UTF-8
fatal: could not parse patch

Whereas i got no similar error with the other patch 2/3 and 4.

I find a way to apply it anyway.

Patrice


On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> From: Dillon Min <dillon.minfei@gmail.com>
> 
> This driver combine tiny/ili9341.c mipi_dbi_interface driver
> with mipi_dpi_interface driver, can support ili9341 with serial
> mode or parallel rgb interface mode by register configuration.
> 
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Link: https://lore.kernel.org/lkml/1590378348-8115-7-git-send-email-dillon.minfei@gmail.com/
> Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> ---
>  drivers/gpu/drm/panel/Kconfig                |   12 +
>  drivers/gpu/drm/panel/Makefile               |    1 +
>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
>  3 files changed, 1298 insertions(+)
>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> 
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 4894913936e9..e4babba17864 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -123,6 +123,18 @@ config DRM_PANEL_ILITEK_IL9322
>  	  Say Y here if you want to enable support for Ilitek IL9322
>  	  QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
>  
> +config DRM_PANEL_ILITEK_ILI9341
> +	tristate "Ilitek ILI9341 240x320 QVGA panels"
> +	depends on OF && SPI
> +	depends on DRM_KMS_HELPER
> +	depends on DRM_KMS_CMA_HELPER
> +	depends on BACKLIGHT_CLASS_DEVICE
> +	select DRM_MIPI_DBI
> +	help
> +	  Say Y here if you want to enable support for Ilitek IL9341
> +	  QVGA (240x320) RGB panels. support serial & parallel rgb
> +	  interface.
> +
>  config DRM_PANEL_ILITEK_ILI9881C
>  	tristate "Ilitek ILI9881C-based panels"
>  	depends on OF
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index cae4d976c069..0ecde184665d 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
>  obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
>  obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
>  obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
> +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
>  obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
>  obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
>  obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
> diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> new file mode 100644
> index 000000000000..f84983cbb250
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> @@ -0,0 +1,1285 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Ilitek ILI9341 TFT LCD drm_panel driver.
> + *
> + * This panel can be configured to support:
> + * - 16-bit parallel RGB interface
> + * - 18-bit parallel RGB interface
> + * - 4-line serial spi interface
> + *
> + * Copyright (C) 2020 Dillon Min <dillon.minfei@gmail.com>
> + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/spi/spi.h>
> +#include <linux/delay.h>
> +#include <video/mipi_display.h>
> +#include <drm/drm_mipi_dbi.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_gem_atomic_helper.h>
> +#include <drm/drm_atomic_helper.h>
> +
> +#include <drm/drm_drv.h>
> +#include <drm/drm_modes.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_print.h>
> +
> +#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
> +#define ILI9341_FRC            0xb1   /* Frame Rate Control register */
> +#define ILI9341_DFC            0xb6   /* Display Function Control register */
> +#define ILI9341_POWER1         0xc0   /* Power Control 1 register */
> +#define ILI9341_POWER2         0xc1   /* Power Control 2 register */
> +#define ILI9341_VCOM1          0xc5   /* VCOM Control 1 register */
> +#define ILI9341_VCOM2          0xc7   /* VCOM Control 2 register */
> +#define ILI9341_POWERA         0xcb   /* Power control A register */
> +#define ILI9341_POWERB         0xcf   /* Power control B register */
> +#define ILI9341_PGAMMA         0xe0   /* Positive Gamma Correction register */
> +#define ILI9341_NGAMMA         0xe1   /* Negative Gamma Correction register */
> +#define ILI9341_DTCA           0xe8   /* Driver timing control A */
> +#define ILI9341_DTCB           0xea   /* Driver timing control B */
> +#define ILI9341_POWER_SEQ      0xed   /* Power on sequence register */
> +#define ILI9341_3GAMMA_EN      0xf2   /* 3 Gamma enable register */
> +#define ILI9341_INTERFACE      0xf6   /* Interface control register */
> +#define ILI9341_PRC            0xf7   /* Pump ratio control register */
> +#define ILI9341_ETMOD	       0xb7   /* Entry mode set */
> +
> +#define ILI9341_MADCTL_BGR	BIT(3)
> +#define ILI9341_MADCTL_MV	BIT(5)
> +#define ILI9341_MADCTL_MX	BIT(6)
> +#define ILI9341_MADCTL_MY	BIT(7)
> +
> +
> +#define ILI9341_POWER_B_LEN	3
> +#define ILI9341_POWER_SEQ_LEN	4
> +#define ILI9341_DTCA_LEN	3
> +#define ILI9341_DTCB_LEN	2
> +#define ILI9341_POWER_A_LEN	5
> +#define ILI9341_DFC_1_LEN	2
> +#define ILI9341_FRC_LEN		2
> +#define ILI9341_VCOM_1_LEN	2
> +#define ILI9341_DFC_2_LEN	4
> +#define ILI9341_COLUMN_ADDR_LEN	4
> +#define ILI9341_PAGE_ADDR_LEN	4
> +#define ILI9341_INTERFACE_LEN	3
> +#define ILI9341_PGAMMA_LEN	15
> +#define ILI9341_NGAMMA_LEN	15
> +#define ILI9341_CA_LEN		3
> +
> +#define ILI9341_PIXEL_DPI_16_BITS	(BIT(6)|BIT(4))
> +#define ILI9341_PIXEL_DPI_18_BITS	(BIT(6)|BIT(5))
> +#define ILI9341_GAMMA_CURVE_1		BIT(0)
> +#define ILI9341_IF_WE_MODE		BIT(0)
> +#define ILI9341_IF_BIG_ENDIAN		0x00
> +#define ILI9341_IF_DM_RGB		BIT(2)
> +#define ILI9341_IF_DM_INTERNAL		0x00
> +#define ILI9341_IF_DM_VSYNC		BIT(3)
> +#define ILI9341_IF_RM_RGB		BIT(1)
> +#define ILI9341_IF_RIM_RGB		0x00
> +
> +#define ILI9341_COLUMN_ADDR		0x00ef
> +#define ILI9341_PAGE_ADDR		0x013f
> +
> +#define ILI9341_RGB_EPL			BIT(0)
> +#define ILI9341_RGB_DPL			BIT(1)
> +#define ILI9341_RGB_HSPL		BIT(2)
> +#define ILI9341_RGB_VSPL		BIT(3)
> +#define ILI9341_RGB_DE_MODE		BIT(6)
> +#define ILI9341_RGB_DISP_PATH_MEM	BIT(7)
> +
> +#define ILI9341_DBI_VCOMH_4P6V		0x23
> +#define ILI9341_DBI_PWR_2_DEFAULT	0x10
> +#define ILI9341_DBI_PRC_NORMAL		0x20
> +#define ILI9341_DBI_VCOM_1_VMH_4P25V	0x3e
> +#define ILI9341_DBI_VCOM_1_VML_1P5V	0x28
> +#define ILI9341_DBI_VCOM_2_DEC_58	0x86
> +#define ILI9341_DBI_FRC_DIVA		0x00
> +#define ILI9341_DBI_FRC_RTNA		0x1b
> +#define ILI9341_DBI_EMS_GAS		BIT(0)
> +#define ILI9341_DBI_EMS_DTS		BIT(1)
> +#define ILI9341_DBI_EMS_GON		BIT(2)
> +/**
> + * ili9341_command - ili9341 command with optional parameter(s)
> + * @ili: struct ili9341
> + * @cmd: Command
> + * @seq...: Optional parameter(s)
> + *
> + * Send command to the controller.
> + *
> + * Returns:
> + * Zero on success, negative error code on failure.
> + */
> +#define ili9341_command(ili, cmd, seq...) \
> +({ \
> +	u8 d[] = { seq }; \
> +	_ili9341_command(ili, cmd, d, ARRAY_SIZE(d)); \
> +})
> +
> +/**
> + * struct ili9341_config - the system specific ILI9341 configuration
> + * @max_spi_speed: 10000000
> + */
> +struct ili9341_config {
> +	u32 max_spi_speed;
> +	/** @mode: the drm display mode */
> +	const struct drm_display_mode mode;
> +	/** @ca: TODO: need comments for this register */
> +	u8 ca[ILI9341_CA_LEN];
> +	/** @power_b: TODO: need comments for this register */
> +	u8 power_b[ILI9341_POWER_B_LEN];
> +	/** @power_seq: TODO: need comments for this register */
> +	u8 power_seq[ILI9341_POWER_SEQ_LEN];
> +	/** @dtca: TODO: need comments for this register */
> +	u8 dtca[ILI9341_DTCA_LEN];
> +	/** @dtcb: TODO: need comments for this register */
> +	u8 dtcb[ILI9341_DTCB_LEN];
> +	/** @power_a: TODO: need comments for this register */
> +	u8 power_a[ILI9341_POWER_A_LEN];
> +	/** @frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
> +	/*
> +	 * Formula to calculate frame frequency:
> +	 * Frame Rate=fosc/(Clocks per line x Division ratio x
> +	 * (Lines+VBP+VFP))
> +	 *
> +	 * Sets the division ratio for internal clocks of Normal mode at MCU
> +	 * interface.
> +	 *
> +	 * fosc : internal oscillator frequency
> +	 * Clocks per line : RTNA setting
> +	 * Division ratio : DIVA setting
> +	 * Lines : total driving line number
> +	 * VBP : back porch line number
> +	 * VFP : front porch line number
> +	 *
> +	 * RTNA [4:0] Frame Rate (Hz)   RTNA [4:0] Frame Rate (Hz)
> +	 * 1 0 0 0 0  119		1 1 0 0 0  79
> +	 * 1 0 0 0 1  112		1 1 0 0 1  76
> +	 * 1 0 0 1 0  106		1 1 0 1 0  73
> +	 * 1 0 0 1 1  100		1 1 0 1 1  70(default)
> +	 * 1 0 1 0 0  95		1 1 1 0 0  68
> +	 * 1 0 1 0 1  90		1 1 1 0 1  65
> +	 * 1 0 1 1 0  86		1 1 1 0 1  63
> +	 * 1 0 1 1 1  83		1 1 1 1 1  61
> +	 *
> +	 * DIVA [1:0] : division ratio for internal clocks when Normal mode.
> +	 *
> +	 * DIVA [1:0] Division Ratio
> +	 * 0 0 fosc
> +	 * 0 1 fosc / 2
> +	 * 1 0 fosc / 4
> +	 * 1 1 fosc / 8
> +	 *
> +	 */
> +	u8 frc[ILI9341_FRC_LEN];
> +	/** @prc: TODO: need comments for this register */
> +	u8 prc;
> +	/** @dfc_1: B6h DISCTRL (Display Function Control) */
> +	/*               D/CX RDX WRX D17-8 D7  D6 D5 D4 D3   D2  D1  D0  HEX
> +	 * Command       0    1   M   XX    1   0  1  1  0    1   1   0   B6h
> +	 * 1st Parameter 1    1   M   XX    0   0  0  0  PTG[1:0] PT[1:0] 0A
> +	 * 2nd Parameter 1    1   M   XX    REV GS SS SM ISC[3:0]         82
> +	 * 3rd Parameter 1    1   M   XX    0   0  NL[5:0]                27
> +	 * 4th Parameter 1    1   M   XX    0   0  PCDIV[5:0]             XX
> +	 *
> +	 * PTG [1:0]: Set the scan mode in non-display area.
> +	 * PTG1 | PTG0 | Gate outputs in   | Source outputs in  | VCOM output
> +	 *               non-display area  | non-display area   |
> +	 * 1      0      Interval scan       Set with the PT[2:0] bits
> +	 *
> +	 * PT [1:0]: Determine source/VCOM output in a non-display area in the
> +	 * partial display mode.
> +	 * 1    0    AGND       AGND       AGND         AGND
> +	 *
> +	 * REV: Select whether the liquid crystal type is normally white type
> +	 * or normally black type.
> +	 * REV   Liquid crystal type
> +	 * 0     Normally black
> +	 * 1     Normally white
> +	 *
> +	 * SS: Select the shift direction of outputs from the source driver.
> +	 * SS    Source Output Scan Direction
> +	 * 0     S1 -> S720
> +	 * 1     S720 -> S1
> +	 *
> +	 * GS: Sets the direction of scan by the gate driver in the range
> +	 * determined by SCN [4:0] and NL [4:0]. The scan direction
> +	 * determined by GS = 0 can be reversed by setting GS = 1.
> +	 *
> +	 * GS     Gate Output Scan Direction
> +	 * 0      G1 -> G320
> +	 * 1      G320 -> G1
> +	 */
> +	u8 dfc_1[ILI9341_DFC_1_LEN];
> +	 /** @power_1: Power Control 1 (C0h) */
> +	 /* VRH [5:0]: Set the GVDD level, which is a reference level for the
> +	 * VCOM level and the grayscale voltage level.
> +	 *
> +	 * VRH[5:0]    GVDD			VRH[5:0]	GVDD
> +	 * 0 0 0 0 0 0 Setting prohibited	1 0 0 0 0 0	4.45 V
> +	 * 0 0 0 0 0 1 Setting prohibited	1 0 0 0 0 1	4.50 V
> +	 * 0 0 0 0 1 0 Setting prohibited	1 0 0 0 1 0	4.55 V
> +	 * 0 0 0 0 1 1 3.00 V			1 0 0 0 1 1	4.60 V
> +	 * 0 0 0 1 0 0 3.05 V			1 0 0 1 0 0	4.65 V
> +	 * 0 0 0 1 0 1 3.10 V			1 0 0 1 0 1	4.70 V
> +	 * 0 0 0 1 1 0 3.15 V			1 0 0 1 1 0	4.75 V
> +	 * 0 0 0 1 1 1 3.20 V			1 0 0 1 1 1	4.80 V
> +	 * 0 0 1 0 0 0 3.25 V			1 0 1 0 0 0	4.85 V
> +	 * 0 0 1 0 0 1 3.30 V			1 0 1 0 0 1	4.90 V
> +	 * 0 0 1 0 1 0 3.35 V			1 0 1 0 1 0	4.95 V
> +	 * 0 0 1 0 1 1 3.40 V			1 0 1 0 1 1	5.00 V
> +	 * 0 0 1 1 0 0 3.45 V			1 0 1 1 0 0	5.05 V
> +	 * 0 0 1 1 0 1 3.50 V			1 0 1 1 0 1	5.10 V
> +	 * 0 0 1 1 1 0 3.55 V			1 0 1 1 1 0	5.15 V
> +	 * 0 0 1 1 1 1 3.60 V			1 0 1 1 1 1	5.20 V
> +	 * 0 1 0 0 0 0 3.65 V			1 1 0 0 0 0	5.25 V
> +	 * 0 1 0 0 0 1 3.70 V			1 1 0 0 0 1	5.30 V
> +	 * 0 1 0 0 1 0 3.75 V			1 1 0 0 1 0	5.35 V
> +	 * 0 1 0 0 1 1 3.80 V			1 1 0 0 1 1	5.40 V
> +	 * 0 1 0 1 0 0 3.85 V			1 1 0 1 0 0	5.45 V
> +	 * 0 1 0 1 0 1 3.90 V			1 1 0 1 0 1	5.50 V
> +	 * 0 1 0 1 1 0 3.95 V			1 1 0 1 1 0	5.55 V
> +	 * 0 1 0 1 1 1 4.00 V			1 1 0 1 1 1	5.60 V
> +	 * 0 1 1 0 0 0 4.05 V			1 1 1 0 0 0	5.65 V
> +	 * 0 1 1 0 0 1 4.10 V			1 1 1 0 0 1	5.70 V
> +	 * 0 1 1 0 1 0 4.15 V			1 1 1 0 1 0	5.75 V
> +	 * 0 1 1 0 1 1 4.20 V			1 1 1 0 1 1	5.80 V
> +	 * 0 1 1 1 0 0 4.25 V			1 1 1 1 0 0	5.85 V
> +	 * 0 1 1 1 0 1 4.30 V			1 1 1 1 0 1	5.90 V
> +	 * 0 1 1 1 1 0 4.35 V			1 1 1 1 1 0	5.95 V
> +	 * 0 1 1 1 1 1 4.40 V			1 1 1 1 1 1	6.00 V
> +	 */
> +	u8 power_1;
> +	/** @power_2: Power Control 2 (C1h) */
> +	/*
> +	 * BT [2:0]: Sets the factor used in the step-up circuits.
> +	 * Select the optimal step-up factor for the operating voltage. To
> +	 * reduce power consumption, set a smaller factor.
> +	 *
> +	 * BT[2:0]   AVDD     VGH      VGL
> +	 * 0 0 0     VCI x 2  VCI x 7  VCI x 4
> +	 * 0 0 1                       VCI x 3
> +	 * 0 1 0              VCI x 6  VCI x 4
> +	 * 0 1 1		       VCI x 3
> +	 *
> +	 */
> +	u8 power_2;
> +	/** @vcom_1: VCOM Control 1(C5h) */
> +	/*
> +	 * VMH [6:0] : Set the VCOMH voltage
> +	 *
> +	 * VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH
> +	 * 0000000  2.700    0100000  3.500    1000000  4.300    1100000  5.100
> +	 * 0000001  2.725    0100001  3.525    1000001  4.325    1100001  5.125
> +	 * 0000010  2.750    0100010  3.550    1000010  4.350    1100010  5.150
> +	 * 0000011  2.775    0100011  3.575    1000011  4.375    1100011  5.175
> +	 * 0000100  2.800    0100100  3.600    1000100  4.400    1100100  5.200
> +	 * 0000101  2.825    0100101  3.625    1000101  4.425    1100101  5.225
> +	 * 0000110  2.850    0100110  3.650    1000110  4.450    1100110  5.250
> +	 * 0000111  2.875    0100111  3.675    1000111  4.475 	 1100111  5.275
> +	 * 0001000  2.900    0101000  3.700    1001000  4.500 	 1101000  5.300
> +	 * 0001001  2.925    0101001  3.725    1001001  4.525 	 1101001  5.325
> +	 * 0001010  2.950    0101010  3.750    1001010  4.550 	 1101010  5.350
> +	 * 0001011  2.975    0101011  3.775    1001011  4.575 	 1101011  5.375
> +	 * 0001100  3.000    0101100  3.800    1001100  4.600 	 1101100  5.400
> +	 * 0001101  3.025    0101101  3.825    1001101  4.625 	 1101101  5.425
> +	 * 0001110  3.050    0101110  3.850    1001110  4.650 	 1101110  5.450
> +	 * 0001111  3.075    0101111  3.875    1001111  4.675 	 1101111  5.475
> +	 * 0010000  3.100    0110000  3.900    1010000  4.700 	 1110000  5.500
> +	 * 0010001  3.125    0110001  3.925    1010001  4.725 	 1110001  5.525
> +	 * 0010010  3.150    0110010  3.950    1010010  4.750 	 1110010  5.550
> +	 * 0010011  3.175    0110011  3.975    1010011  4.775 	 1110011  5.575
> +	 * 0010100  3.200    0110100  4.000    1010100  4.800 	 1110100  5.600
> +	 * 0010101  3.225    0110101  4.025    1010101  4.825 	 1110101  5.625
> +	 * 0010110  3.250    0110110  4.050    1010110  4.850 	 1110110  5.650
> +	 * 0010111  3.275    0110111  4.075    1010111  4.875 	 1110111  5.675
> +	 * 0011000  3.300    0111000  4.100    1011000  4.900 	 1111000  5.700
> +	 * 0011001  3.325    0111001  4.125    1011001  4.925 	 1111001  5.725
> +	 * 0011010  3.350    0111010  4.150    1011010  4.950 	 1111010  5.750
> +	 * 0011011  3.375    0111011  4.175    1011011  4.975 	 1111011  5.775
> +	 * 0011100  3.400    0111100  4.200    1011100  5.000 	 1111100  5.800
> +	 * 0011101  3.425    0111101  4.225    1011101  5.025 	 1111101  5.825
> +	 * 0011110  3.450    0111110  4.250    1011110  5.050 	 1111110  5.850
> +	 * 0011111  3.475    0111111  4.275    1011111  5.075    1111111  5.875
> +	 *
> +	 * VML[6:0] : Set the VCOML voltage
> +	 *
> +	 * VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML
> +	 * 0000000 -2.500 0100000 -1.700 1000000 -0.900 1100000 -0.100
> +	 * 0000001 -2.475 0100001 -1.675 1000001 -0.875 1100001 -0.075
> +	 * 0000010 -2.450 0100010 -1.650 1000010 -0.850 1100010 -0.050
> +	 * 0000011 -2.425 0100011 -1.625 1000011 -0.825 1100011 -0.025
> +	 * 0000100 -2.400 0100100 -1.600 1000100 -0.800 1100100 0
> +	 * 0000101 -2.375 0100101 -1.575 1000101 -0.775 1100101 Reserved
> +	 * 0000110 -2.350 0100110 -1.550 1000110 -0.750 1100110 Reserved
> +	 * 0000111 -2.325 0100111 -1.525 1000111 -0.725 1100111 Reserved
> +	 * 0001000 -2.300 0101000 -1.500 1001000 -0.700 1101000 Reserved
> +	 * 0001001 -2.275 0101001 -1.475 1001001 -0.675 1101001 Reserved
> +	 * 0001010 -2.250 0101010 -1.450 1001010 -0.650 1101010 Reserved
> +	 * 0001011 -2.225 0101011 -1.425 1001011 -0.625 1101011 Reserved
> +	 * 0001100 -2.200 0101100 -1.400 1001100 -0.600 1101100 Reserved
> +	 * 0001101 -2.175 0101101 -1.375 1001101 -0.575 1101101 Reserved
> +	 * 0001110 -2.150 0101110 -1.350 1001110 -0.550 1101110 Reserved
> +	 * 0001111 -2.125 0101111 -1.325 1001111 -0.525 1101111 Reserved
> +	 * 0010000 -2.100 0110000 -1.300 1010000 -0.500 1110000 Reserved
> +	 * 0010001 -2.075 0110001 -1.275 1010001 -0.475 1110001 Reserved
> +	 * 0010010 -2.050 0110010 -1.250 1010010 -0.450 1110010 Reserved
> +	 * 0010011 -2.025 0110011 -1.225 1010011 -0.425 1110011 Reserved
> +	 * 0010100 -2.000 0110100 -1.200 1010100 -0.400 1110100 Reserved
> +	 * 0010101 -1.975 0110101 -1.175 1010101 -0.375 1110101 Reserved
> +	 * 0010110 -1.950 0110110 -1.150 1010110 -0.350 1110110 Reserved
> +	 * 0010111 -1.925 0110111 -1.125 1010111 -0.325 1110111 Reserved
> +	 * 0011000 -1.900 0111000 -1.100 1011000 -0.300 1111000 Reserved
> +	 * 0011001 -1.875 0111001 -1.075 1011001 -0.275 1111001 Reserved
> +	 * 0011010 -1.850 0111010 -1.050 1011010 -0.250 1111010 Reserved
> +	 * 0011011 -1.825 0111011 -1.025 1011011 -0.225 1111011 Reserved
> +	 * 0011100 -1.800 0111100 -1.000 1011100 -0.200 1111100 Reserved
> +	 * 0011101 -1.775 0111101 -0.975 1011101 -0.175 1111101 Reserved
> +	 * 0011110 -1.750 0111110 -0.950 1011110 -0.150 1111110 Reserved
> +	 * 0011111 -1.725 0111111 -0.925 1011111 -0.125 1111111 Reserved
> +	 */
> +	u8 vcom_1[ILI9341_VCOM_1_LEN];
> +	/** @vcom_2: VCOM Control 2(C7h) */
> +	/*
> +	 * C7h		VMCTRL1 (VCOM Control 1)
> +	 *		D/CX RDX WRX D17-8 D7  D6  D5 D4 D3 D2 D1 D0 HEX
> +	 * Command 	0    1   M   XX    1   1   0  0  0  1  1  1  C7h
> +	 * Parameter 	1    1   M   XX    nVM VMF[6:0]              C0
> +	 *
> +	 * nVM: nVM equals to “0” after power on reset and VCOM offset
> +	 * equals to program MTP value. When nVM set to “1”, setting
> +	 * of VMF [6:0] becomes valid and VCOMH/VCOML can be adjusted.
> +	 *
> +	 * VMF [6:0]: Set the VCOM offset voltage.
> +	 */
> +	u8 vcom_2;
> +	/** @address_mode: Memory Access Control (36h) */
> +	/*
> +	 * 36h 		MADCTL (Memory Access Control)
> +	 * 		D/CX RDX WRX D17-8 D7 D6 D5 D4 D3  D2 D1 D0 HEX
> +	 * Command 	0    1   M   XX    0  0  1  1  0   1  1  0  36h
> +	 * Parameter 	1    1   M   XX    MY MX MV ML BGR MH 0  0  00
> +	 *
> +	 * This command defines read/write scanning direction of frame memory.
> +	 * This command makes no change on the other driver status.
> +	 *
> +	 * Bit  Name 			 Description
> +	 * MY   Row Address Order
> +	 * MX   Column Address Order
> +	 * MV 	Row / Column Exchange 	 These 3 bits control MCU to memory
> +	 * 				 write/read direction.
> +	 * ML 	Vertical Refresh Order 	 LCD vertical refresh direction control.
> +	 * BGR 	RGB-BGR Order		 Color selector switch control
> +	 *                               (0=RGB color filter panel, 1=BGR
> +	 *                               color filter panel)
> +	 * MH 	Horizontal Refresh ORDER LCD horizontal refreshing
> +	 * direction control.
> +	 *
> +	 * Note: When BGR bit is changed, the new setting is active
> +	 * immediately without update the content in Frame Memory again.
> +	 *
> +	 */
> +	u8 address_mode;
> +	/** @g3amma_en: TODO: need comments for this register */
> +	u8 g3amma_en;
> +	/** @rgb_interface: RGB Interface Signal Control (B0h) */
> +	/*
> +	 * B0h 		IFMODE (Interface Mode Control)
> +	 * 		D/CX RDX WRX D17-8 D7 	       D6     D5     D4 D3   D2   D1  D0  HEX
> +	 * Command 	0    1   M   XX    1 	       0      1      1  0    0    0   0   B0h
> +	 * Parameter 	1    1   M   XX    ByPass_MODE RCM[1] RCM[0] 0  VSPL HSPL DPL EPL 40
> +	 *
> +	 * Sets the operation status of the display interface. The setting
> +	 * becomes effective as soon as the command is received.
> +	 * EPL: DE polarity (“0”= High enable for RGB interface, “1”= Low
> +	 * enable for RGB interface)
> +	 *
> +	 * DPL: DOTCLK polarity set (“0”= data fetched at the rising time,
> +	 * “1”= data fetched at the falling time)
> +	 *
> +	 * HSPL: HSYNC polarity (“0”= Low level sync clock, “1”= High
> +	 * level sync clock)
> +	 *
> +	 * VSPL: VSYNC polarity (“0”= Low level sync clock, “1”= High
> +	 * level sync clock)
> +	 *
> +	 * RCM [1:0]: RGB interface selection (refer to the RGB interface
> +	 * section).
> +	 *
> +	 * ByPass_MODE: Select display data path whether Memory or Direct to
> +	 * Shift register when RGB Interface is used.
> +	 *
> +	 * ByPass_MODE 	Display Data Path
> +	 * 0 		Direct to Shift Register (default)
> +	 * 1 		Memory
> +	 */
> +	u8 rgb_interface;
> +	/** @dfc_2: refer to dfc_1 */
> +	u8 dfc_2[ILI9341_DFC_2_LEN];
> +	/** @column_addr: Column Address Set (2Ah) */
> +	/* This command is used to define area of frame memory where MCU can
> +	 * access. This command makes no change on the
> +	 * other driver status. The values of SC [15:0] and EC [15:0] are
> +	 * referred when RAMWR command comes. Each value
> +	 * represents one column line in the Frame Memory.
> +	 */
> +	u8 column_addr[ILI9341_COLUMN_ADDR_LEN];
> +	/** @page_addr: Page Address Set (2Bh) */
> +	/* This command is used to define area of frame memory where MCU can
> +	 * access. This command makes no change on the
> +	 * other driver status. The values of SP [15:0] and EP [15:0] are
> +	 * referred when RAMWR command comes. Each value
> +	 * represents one Page line in the Frame Memory.
> +	 */
> +	u8 page_addr[ILI9341_PAGE_ADDR_LEN];
> +	/** @interface: Interface Control (F6h) */
> +	/*
> +	 * F6h 		IFCTL (16bits Data Format Selection)
> +	 * 	        D/CX RDX WRX D17-8 D7   D6   D5     D4     D3      D2     D1     D0      HEX
> +	 * Command      0    1   M   XX    1    1    1      1      0       1      1      0       F6h
> +	 * 1stParameter 1    1   M   XX    MY   MX   MV
> +	 * 				   _EOR _EOR _EOR   0      BGR_EOR 0      0      WE MODE 01
> +	 * 2ndParameter 1    1   M   XX    0    0    EPF[1] EPF[0] 0       0      MDT[1] MDT[0]  00
> +	 * 3rdParameter 1    1   M   XX    0    0    ENDIAN 0      DM[1]   DM[0]  RM     RIM     00
> +	 *
> +	 */
> +	u8 interface[ILI9341_INTERFACE_LEN];
> +	/** @pixel_format: This command sets the pixel format for the RGB image data used by */
> +	/* the interface. DPI [2:0] is the pixel format select of RGB
> +	 * interface and DBI [2:0] is the pixel format of MCU interface. If a
> +	 * particular interface, either RGB interface or MCU interface, is
> +	 * not used then the corresponding bits in the parameter are ignored.
> +	 * The pixel format is shown in the table below.
> +	 *
> +	 * DPI[2:0] 	RGB Interface Format 	DBI[2:0] MCU Interface Format
> +	 * 0 0 0 	Reserved 		0 0 0 	 Reserved
> +	 * 0 0 1 	Reserved 		0 0 1 	 Reserved
> +	 * 0 1 0 	Reserved 		0 1 0 	 Reserved
> +	 * 0 1 1 	Reserved 		0 1 1 	 Reserved
> +	 * 1 0 0 	Reserved 		1 0 0  	 Reserved
> +	 * 1 0 1 	16 bits / pixel 	1 0 1    16 bits / pixel
> +	 * 1 1 0 	18 bits / pixel 	1 1 0 	 18 bits / pixel
> +	 * 1 1 1 	Reserved 		1 1 1 	 Reserved
> +	 *
> +	 */
> +	u8 pixel_format;
> +	/** @gamma_curve: This command is used to select the desired Gamma curve for the */
> +	/* current display. A maximum of 4 fixed gamma curves can
> +	 * be selected. The curve is selected by setting the appropriate bit
> +	 * in the parameter as described in the Table:
> +	 *
> +	 * GC [7:0] 	Curve Selected
> +	 * 01h 		Gamma curve 1 (G2.2)
> +	 * 02h 		---
> +	 * 04h 		---
> +	 * 08h 		---
> +	 */
> +	u8 gamma_curve;
> +	/** @pgamma: Positive Gamma Correction (E0h) */
> +	/*
> +	 * Set the gray scale voltage to adjust the gamma characteristics of
> +	 * the TFT panel.
> +	 */
> +	u8 pgamma[ILI9341_PGAMMA_LEN];
> +	/** @ngamma: Negative Gamma Correction (E1h) */
> +	/*
> +	 * Set the gray scale voltage to adjust the gamma characteristics of
> +	 * the TFT panel.
> +	 */
> +	u8 ngamma[ILI9341_NGAMMA_LEN];
> +};
> +
> +struct ili9341 {
> +	struct device *dev;
> +	const struct ili9341_config *conf;
> +	struct drm_panel panel;
> +	struct gpio_desc *reset_gpio;
> +	struct gpio_desc *dc_gpio;
> +	u32 max_spi_speed;
> +	struct regulator *vcc;
> +};
> +
> +/*
> + * The Stm32f429-disco board has a panel ili9341 connected to ltdc controller
> + */
> +static const struct ili9341_config ili9341_stm32f429_disco_data = {
> +	.max_spi_speed = 10000000,
> +	.mode = {
> +		.clock = 6100,
> +		.hdisplay = 240,
> +		.hsync_start = 240 + 10,/* hfp 10 */
> +		.hsync_end = 240 + 10 + 10,/* hsync 10 */
> +		.htotal = 240 + 10 + 10 + 20,/* hbp 20 */
> +		.vdisplay = 320,
> +		.vsync_start = 320 + 4,/* vfp 4 */
> +		.vsync_end = 320 + 4 + 2,/* vsync 2 */
> +		.vtotal = 320 + 4 + 2 + 2,/* vbp 2 */
> +		.flags = 0,
> +		.width_mm = 65,
> +		.height_mm = 50,
> +		.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +	},
> +	/* TODO: need comments for this register */
> +	.ca = {0xc3, 0x08, 0x50},
> +	/* TODO: need comments for this register */
> +	.power_b = {0x00, 0xc1, 0x30},
> +	/* TODO: need comments for this register */
> +	.power_seq = {0x64, 0x03, 0x12, 0x81},
> +	/* TODO: need comments for this register */
> +	.dtca = {0x85, 0x00, 0x78},
> +	/* TODO: need comments for this register */
> +	.power_a = {0x39, 0x2c, 0x00, 0x34, 0x02},
> +	/* TODO: need comments for this register */
> +	.prc = 0x20,
> +	/* TODO: need comments for this register */
> +	.dtcb = {0x00, 0x00},
> +	/* 0x00 fosc, 0x1b 70hz */
> +	.frc = {0x00, 0x1b},
> +	/* 0x0a Interval scan, AGND AGND AGND AGND
> +	 * 0xa2 Normally white, G1 -> G320, S720 -> S1,
> +	 *	Scan Cycle 5 frames,85ms
> +	 */
> +	.dfc_1 = {0x0a, 0xa2},
> +	/* 0x10 3.65v */
> +	.power_1 = 0x10,
> +	/* 0x10 AVDD=vci*2, VGH=vci*7, VGL=-vci*4 */
> +	.power_2 = 0x10,
> +	/* 0x45 VCOMH 4.425v, 0x15 VCOML -1.975*/
> +	.vcom_1 = {0x45, 0x15},
> +	/* 0x90 offset voltage, VMH-48, VML-48 */
> +	.vcom_2 = 0x90,
> +	/* 0xc8 Row Address Order, Column Address Order
> +	 * 	BGR 1
> +	 */
> +	.address_mode = 0xc8,
> +	.g3amma_en = 0x00,
> +	/* 0xc2
> +	 * Display Data Path: Memory
> +	 * RGB: DE mode
> +	 * DOTCLK polarity set (data fetched at the falling time)
> +	 */
> +	.rgb_interface = ILI9341_RGB_DISP_PATH_MEM |
> +			ILI9341_RGB_DE_MODE |
> +			ILI9341_RGB_DPL,
> +	/*
> +	 * 0x0a
> +	 * Gate outputs in non-display area: Interval scan
> +	 * Determine source/VCOM output in a non-display area in the partial
> +	 * display mode: AGND AGND AGND AGND
> +	 *
> +	 * 0xa7
> +	 * Scan Cycle: 15 frames
> +	 * fFLM = 60Hz: 255ms
> +	 * Liquid crystal type: Normally white
> +	 * Gate Output Scan Direction: G1 -> G320
> +	 * Source Output Scan Direction: S720 -> S1
> +	 *
> +	 * 0x27
> +	 * LCD Driver Line: 320 lines
> +	 *
> +	 * 0x04
> +	 * PCDIV: 4
> +	 */
> +	.dfc_2 = {0x0a, 0xa7, 0x27, 0x04},
> +	/* column address: 240 */
> +	.column_addr = {0x00, 0x00, (ILI9341_COLUMN_ADDR >> 4) & 0xff,
> +				ILI9341_COLUMN_ADDR & 0xff},
> +	/* page address: 320 */
> +	.page_addr = {0x00, 0x00, (ILI9341_PAGE_ADDR >> 4) & 0xff,
> +				ILI9341_PAGE_ADDR & 0xff},
> +	/* Memory write control: When the transfer number of data exceeds
> +	 * (EC-SC+1)*(EP-SP+1), the column and page number will be
> +	 * reset, and the exceeding data will be written into the following
> +	 * column and page.
> +	 * Display Operation Mode: RGB Interface Mode
> +	 * Interface for RAM Access: RGB interface
> +	 * 16- bit RGB interface (1 transfer/pixel)
> +	 */
> +	.interface = {ILI9341_IF_WE_MODE, 0x00,
> +			ILI9341_IF_DM_RGB | ILI9341_IF_RM_RGB},
> +	/* DPI: 16 bits / pixel */
> +	.pixel_format = ILI9341_PIXEL_DPI_16_BITS,
> +	/* Curve Selected: Gamma curve 1 (G2.2) */
> +	.gamma_curve = ILI9341_GAMMA_CURVE_1,
> +	.pgamma = {0x0f, 0x29, 0x24, 0x0c, 0x0e,
> +			0x09, 0x4e, 0x78, 0x3c, 0x09,
> +			0x13, 0x05, 0x17, 0x11, 0x00},
> +	.ngamma = {0x00, 0x16, 0x1b, 0x04, 0x11,
> +			0x07, 0x31, 0x33, 0x42, 0x05,
> +			0x0c, 0x0a, 0x28, 0x2f, 0x0f},
> +};
> +
> +static inline struct ili9341 *panel_to_ili9341(struct drm_panel *panel)
> +{
> +	return container_of(panel, struct ili9341, panel);
> +}
> +
> +static int ili9341_spi_transfer(struct spi_device *spi, u32 speed_hz,
> +			  u8 bpw, const void *buf, size_t len)
> +{
> +	size_t max_chunk = spi_max_transfer_size(spi);
> +	struct spi_transfer tr = {
> +		.bits_per_word = bpw,
> +		.speed_hz = speed_hz,
> +		.len = len,
> +	};
> +	struct spi_message m;
> +	size_t chunk;
> +	int ret;
> +
> +	spi_message_init_with_transfers(&m, &tr, 1);
> +
> +	while (len) {
> +		chunk = min(len, max_chunk);
> +
> +		tr.tx_buf = buf;
> +		tr.len = chunk;
> +		buf += chunk;
> +		len -= chunk;
> +
> +		ret = spi_sync(spi, &m);
> +		if (ret) {
> +			dev_err(&spi->dev, "spi_sync error: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int _ili9341_command(struct ili9341 *ili, u8 cmd, const void *data,
> +				    size_t count)
> +{
> +	struct spi_device *spi = to_spi_device(ili->dev);
> +	int ret = 0;
> +
> +	gpiod_set_value_cansleep(ili->dc_gpio, 0);
> +
> +	ret = ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
> +					(const void *)&cmd, 1);
> +	if (ret || data == NULL || count == 0) {
> +		return ret;
> +	}
> +
> +	gpiod_set_value_cansleep(ili->dc_gpio, 1);
> +
> +	return ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
> +		data, count);
> +}
> +
> +static int ili9341_dpi_init(struct ili9341 *ili)
> +{
> +	int ret;
> +	ret = _ili9341_command(ili, 0xca,
> +			ili->conf->ca,
> +			ILI9341_CA_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_POWERB,
> +			ili->conf->power_b,
> +			ILI9341_POWER_B_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_POWER_SEQ,
> +			ili->conf->power_seq,
> +			ILI9341_POWER_SEQ_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_DTCA,
> +			ili->conf->dtca,
> +			ILI9341_DTCA_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_POWERA,
> +			ili->conf->power_a,
> +			ILI9341_POWER_A_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_PRC,
> +			&ili->conf->prc,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_DTCB,
> +			ili->conf->dtcb,
> +			ILI9341_DTCB_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_FRC,
> +			ili->conf->frc,
> +			ILI9341_FRC_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_DFC,
> +			ili->conf->dfc_1,
> +			ILI9341_DFC_1_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_POWER1,
> +			&ili->conf->power_1,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_POWER2,
> +			&ili->conf->power_2,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_VCOM1,
> +			ili->conf->vcom_1,
> +			ILI9341_VCOM_1_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_VCOM2,
> +			&ili->conf->vcom_2,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, MIPI_DCS_SET_ADDRESS_MODE,
> +			&ili->conf->address_mode,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_3GAMMA_EN,
> +			&ili->conf->g3amma_en,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_RGB_INTERFACE,
> +			&ili->conf->rgb_interface,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_DFC,
> +			ili->conf->dfc_2,
> +			ILI9341_DFC_2_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, MIPI_DCS_SET_COLUMN_ADDRESS,
> +			ili->conf->column_addr,
> +			ILI9341_COLUMN_ADDR_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, MIPI_DCS_SET_PAGE_ADDRESS,
> +			ili->conf->page_addr,
> +			ILI9341_PAGE_ADDR_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_INTERFACE,
> +			ili->conf->interface,
> +			ILI9341_INTERFACE_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, MIPI_DCS_SET_PIXEL_FORMAT,
> +			&ili->conf->pixel_format,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
> +	if (ret)
> +		return ret;
> +
> +	msleep(200);
> +	ret = _ili9341_command(ili, MIPI_DCS_SET_GAMMA_CURVE,
> +			&ili->conf->gamma_curve,
> +			1);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_PGAMMA,
> +			ili->conf->pgamma,
> +			ILI9341_PGAMMA_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = _ili9341_command(ili, ILI9341_NGAMMA,
> +			ili->conf->ngamma,
> +			ILI9341_NGAMMA_LEN);
> +	if (ret)
> +		return ret;
> +
> +	ret = ili9341_command(ili, MIPI_DCS_EXIT_SLEEP_MODE);
> +	if (ret)
> +		return ret;
> +
> +	msleep(200);
> +	ret = ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
> +	if (ret)
> +		return ret;
> +
> +	ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
> +	if (ret)
> +		return ret;
> +
> +	dev_info(ili->dev, "initialized display rgb interface\n");
> +
> +	return 0;
> +}
> +
> +static int ili9341_dpi_power_on(struct ili9341 *ili)
> +{
> +	int ret = 0;
> +
> +	/* Assert RESET */
> +	gpiod_set_value(ili->reset_gpio, 1);
> +
> +	/* Enable power */
> +	if (!IS_ERR(ili->vcc)) {
> +		ret = regulator_enable(ili->vcc);
> +		if (ret < 0) {
> +			dev_err(ili->dev, "unable to enable vcc\n");
> +			return ret;
> +		}
> +	}
> +	msleep(20);
> +
> +	/* De-assert RESET */
> +	gpiod_set_value(ili->reset_gpio, 0);
> +	msleep(10);
> +
> +	return 0;
> +}
> +
> +static int ili9341_dpi_power_off(struct ili9341 *ili)
> +{
> +	/* Assert RESET */
> +	gpiod_set_value(ili->reset_gpio, 1);
> +
> +	/* Disable power */
> +	if (!IS_ERR(ili->vcc))
> +		return regulator_disable(ili->vcc);
> +
> +	return 0;
> +}
> +
> +static int ili9341_dpi_disable(struct drm_panel *panel)
> +{
> +	struct ili9341 *ili = panel_to_ili9341(panel);
> +
> +	ili9341_command(ili, MIPI_DCS_SET_DISPLAY_OFF);
> +
> +	return 0;
> +}
> +
> +static int ili9341_dpi_unprepare(struct drm_panel *panel)
> +{
> +	struct ili9341 *ili = panel_to_ili9341(panel);
> +
> +	return ili9341_dpi_power_off(ili);
> +}
> +
> +static int ili9341_dpi_prepare(struct drm_panel *panel)
> +{
> +	struct ili9341 *ili = panel_to_ili9341(panel);
> +	int ret;
> +
> +	ret = ili9341_dpi_power_on(ili);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = ili9341_dpi_init(ili);
> +	if (ret < 0)
> +		ili9341_dpi_unprepare(panel);
> +
> +	return ret;
> +}
> +
> +static int ili9341_dpi_enable(struct drm_panel *panel)
> +{
> +	struct ili9341 *ili = panel_to_ili9341(panel);
> +
> +	ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
> +
> +	return 0;
> +}
> +
> +static int ili9341_dpi_get_modes(struct drm_panel *panel,
> +				struct drm_connector *connector)
> +{
> +	struct ili9341 *ili = panel_to_ili9341(panel);
> +	struct drm_device *drm = connector->dev;
> +	struct drm_display_mode *mode;
> +	struct drm_display_info *info;
> +
> +	info = &connector->display_info;
> +	info->width_mm = ili->conf->mode.width_mm;
> +	info->height_mm = ili->conf->mode.height_mm;
> +
> +	if (ili->conf->rgb_interface & ILI9341_RGB_DPL)
> +		info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
> +	else
> +		info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
> +
> +	if (ili->conf->rgb_interface & ILI9341_RGB_EPL)
> +		info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
> +	else
> +		info->bus_flags |= DRM_BUS_FLAG_DE_HIGH;
> +
> +	mode = drm_mode_duplicate(drm, &ili->conf->mode);
> +	if (!mode) {
> +		DRM_ERROR("bad mode or failed to add mode\n");
> +		return -EINVAL;
> +	}
> +	drm_mode_set_name(mode);
> +
> +	/* Set up the polarity */
> +	if (ili->conf->rgb_interface & ILI9341_RGB_HSPL)
> +		mode->flags |= DRM_MODE_FLAG_PHSYNC;
> +	else
> +		mode->flags |= DRM_MODE_FLAG_NHSYNC;
> +
> +	if (ili->conf->rgb_interface & ILI9341_RGB_VSPL)
> +		mode->flags |= DRM_MODE_FLAG_PVSYNC;
> +	else
> +		mode->flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +	drm_mode_probed_add(connector, mode);
> +
> +	return 1; /* Number of modes */
> +}
> +
> +static const struct drm_panel_funcs ili9341_dpi_funcs = {
> +	.disable = ili9341_dpi_disable,
> +	.unprepare = ili9341_dpi_unprepare,
> +	.prepare = ili9341_dpi_prepare,
> +	.enable = ili9341_dpi_enable,
> +	.get_modes = ili9341_dpi_get_modes,
> +};
> +
> +static int ili9341_dpi_probe(struct spi_device *spi)
> +{
> +	int ret;
> +	struct device *dev = &spi->dev;
> +	struct ili9341 *ili;
> +
> +	ili = devm_kzalloc(dev, sizeof(struct ili9341), GFP_KERNEL);
> +	if (!ili)
> +		return -ENOMEM;
> +
> +	spi_set_drvdata(spi, ili);
> +
> +	ili->dev = dev;
> +	/*
> +	 * Every new incarnation of this display must have a unique
> +	 * data entry for the system in this driver.
> +	 */
> +	ili->conf = of_device_get_match_data(dev);
> +	if (!ili->conf) {
> +		dev_err(dev, "missing device configuration\n");
> +		return -ENODEV;
> +	}
> +
> +	ili->vcc = devm_regulator_get_optional(dev, "vcc");
> +	if (IS_ERR(ili->vcc))
> +		dev_err(dev, "get optional vcc failed\n");
> +
> +	ili->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> +		GPIOD_OUT_HIGH);
> +	if (IS_ERR(ili->reset_gpio)) {
> +		dev_err(dev, "failed to get RESET GPIO\n");
> +		return PTR_ERR(ili->reset_gpio);
> +	}
> +
> +	ili->dc_gpio = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
> +	if (IS_ERR(ili->dc_gpio)) {
> +		dev_err(dev, "failed to get DC GPIO\n");
> +		return PTR_ERR(ili->dc_gpio);
> +	}
> +
> +	spi->bits_per_word = 8;
> +	ret = spi_setup(spi);
> +	if (ret < 0) {
> +		dev_err(dev, "spi setup failed.\n");
> +		return ret;
> +	}
> +
> +	ili->max_spi_speed = ili->conf->max_spi_speed;
> +
> +	drm_panel_init(&ili->panel, dev, &ili9341_dpi_funcs,
> +		       DRM_MODE_CONNECTOR_DPI);
> +
> +	drm_panel_add(&ili->panel);
> +
> +	return 0;
> +}
> +
> +
> +
> +static void ili9341_dbi_enable(struct drm_simple_display_pipe *pipe,
> +			     struct drm_crtc_state *crtc_state,
> +			     struct drm_plane_state *plane_state)
> +{
> +	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
> +	struct mipi_dbi *dbi = &dbidev->dbi;
> +	u8 addr_mode;
> +	int ret, idx;
> +
> +	if (!drm_dev_enter(pipe->crtc.dev, &idx))
> +		return;
> +
> +	DRM_DEBUG_KMS("\n");
> +
> +	ret = mipi_dbi_poweron_conditional_reset(dbidev);
> +	if (ret < 0)
> +		goto out_exit;
> +	if (ret == 1)
> +		goto out_enable;
> +
> +	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
> +
> +	mipi_dbi_command(dbi, ILI9341_POWERB, 0x00, 0xc1, 0x30);
> +	mipi_dbi_command(dbi, ILI9341_POWER_SEQ, 0x64, 0x03, 0x12, 0x81);
> +	mipi_dbi_command(dbi, ILI9341_DTCA, 0x85, 0x00, 0x78);
> +	mipi_dbi_command(dbi, ILI9341_POWERA, 0x39, 0x2c, 0x00, 0x34, 0x02);
> +	mipi_dbi_command(dbi, ILI9341_PRC, ILI9341_DBI_PRC_NORMAL);
> +	mipi_dbi_command(dbi, ILI9341_DTCB, 0x00, 0x00);
> +
> +	/* Power Control */
> +	mipi_dbi_command(dbi, ILI9341_POWER1, ILI9341_DBI_VCOMH_4P6V);
> +	mipi_dbi_command(dbi, ILI9341_POWER2, ILI9341_DBI_PWR_2_DEFAULT);
> +	/* VCOM */
> +	mipi_dbi_command(dbi, ILI9341_VCOM1, ILI9341_DBI_VCOM_1_VMH_4P25V,
> +						ILI9341_DBI_VCOM_1_VML_1P5V);
> +	mipi_dbi_command(dbi, ILI9341_VCOM2, ILI9341_DBI_VCOM_2_DEC_58);
> +
> +	/* Memory Access Control */
> +	mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT,
> +				MIPI_DCS_PIXEL_FMT_16BIT);
> +
> +	/* Frame Rate */
> +	mipi_dbi_command(dbi, ILI9341_FRC, ILI9341_DBI_FRC_DIVA & 0x03,
> +						ILI9341_DBI_FRC_RTNA & 0x1f);
> +
> +	/* Gamma */
> +	mipi_dbi_command(dbi, ILI9341_3GAMMA_EN, 0x00);
> +	mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, ILI9341_GAMMA_CURVE_1);
> +	mipi_dbi_command(dbi, ILI9341_PGAMMA,
> +			 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
> +			 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
> +	mipi_dbi_command(dbi, ILI9341_NGAMMA,
> +			 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
> +			 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
> +
> +	/* DDRAM */
> +	mipi_dbi_command(dbi, ILI9341_ETMOD, ILI9341_DBI_EMS_GAS |
> +						ILI9341_DBI_EMS_DTS |
> +						ILI9341_DBI_EMS_GON);
> +
> +	/* Display */
> +	mipi_dbi_command(dbi, ILI9341_DFC, 0x08, 0x82, 0x27, 0x00);
> +	mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
> +	msleep(100);
> +
> +	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
> +	msleep(100);
> +
> +out_enable:
> +	switch (dbidev->rotation) {
> +	default:
> +		addr_mode = ILI9341_MADCTL_MX;
> +		break;
> +	case 90:
> +		addr_mode = ILI9341_MADCTL_MV;
> +		break;
> +	case 180:
> +		addr_mode = ILI9341_MADCTL_MY;
> +		break;
> +	case 270:
> +		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
> +			    ILI9341_MADCTL_MX;
> +		break;
> +	}
> +	addr_mode |= ILI9341_MADCTL_BGR;
> +	mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
> +	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
> +	DRM_DEBUG_KMS("initialized display serial interface\n");
> +out_exit:
> +	drm_dev_exit(idx);
> +}
> +
> +static const struct drm_simple_display_pipe_funcs ili9341_dbi_funcs = {
> +	.enable = ili9341_dbi_enable,
> +	.disable = mipi_dbi_pipe_disable,
> +	.update = mipi_dbi_pipe_update,
> +	.prepare_fb = drm_gem_simple_display_pipe_prepare_fb,
> +};
> +
> +static const struct drm_display_mode ili9341_dbi_mode = {
> +	DRM_SIMPLE_MODE(240, 320, 37, 49),
> +};
> +
> +DEFINE_DRM_GEM_CMA_FOPS(ili9341_dbi_fops);
> +
> +static struct drm_driver ili9341_dbi_driver = {
> +	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> +	.fops			= &ili9341_dbi_fops,
> +	DRM_GEM_CMA_DRIVER_OPS_VMAP,
> +	.debugfs_init		= mipi_dbi_debugfs_init,
> +	.name			= "ili9341",
> +	.desc			= "Ilitek ILI9341",
> +	.date			= "20180514",
> +	.major			= 1,
> +	.minor			= 0,
> +};
> +static int ili9341_dbi_probe(struct spi_device *spi)
> +{
> +	struct mipi_dbi_dev *dbidev;
> +	struct drm_device *drm;
> +	struct mipi_dbi *dbi;
> +	struct gpio_desc *dc;
> +	struct device *dev = &spi->dev;
> +	u32 rotation = 0;
> +	int ret;
> +
> +	dbidev = devm_drm_dev_alloc(dev, &ili9341_dbi_driver,
> +				    struct mipi_dbi_dev, drm);
> +	if (IS_ERR(dbidev))
> +		return PTR_ERR(dbidev);
> +
> +	dbi = &dbidev->dbi;
> +	drm = &dbidev->drm;
> +
> +	drm_mode_config_init(drm);
> +
> +	dbi->reset = devm_gpiod_get_optional(dev, "reset",
> +					GPIOD_OUT_HIGH);
> +	if (IS_ERR(dbi->reset)) {
> +		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
> +		return PTR_ERR(dbi->reset);
> +	}
> +
> +	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
> +	if (IS_ERR(dc)) {
> +		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
> +		return PTR_ERR(dc);
> +	}
> +
> +	dbidev->regulator = devm_regulator_get_optional(dev, "vcc");
> +	if (IS_ERR(dbidev->regulator))
> +		dev_err(dev, "get optional vcc failed\n");
> +
> +	dbidev->backlight = devm_of_find_backlight(dev);
> +	if (IS_ERR(dbidev->backlight))
> +		return PTR_ERR(dbidev->backlight);
> +
> +	device_property_read_u32(dev, "rotation", &rotation);
> +
> +	ret = mipi_dbi_spi_init(spi, dbi, dc);
> +	if (ret)
> +		return ret;
> +
> +	ret = mipi_dbi_dev_init(dbidev, &ili9341_dbi_funcs,
> +					&ili9341_dbi_mode, rotation);
> +	if (ret)
> +		return ret;
> +
> +	drm_mode_config_reset(drm);
> +
> +	ret = drm_dev_register(drm, 0);
> +	if (ret)
> +		return ret;
> +
> +	spi_set_drvdata(spi, drm);
> +
> +	drm_fbdev_generic_setup(drm, 0);
> +
> +	return 0;
> +}
> +static int ili9341_probe(struct spi_device *spi)
> +{
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +
> +	if (!strcmp(id->name, "sf-tc240t-9370-t"))
> +		return ili9341_dpi_probe(spi);
> +	else if (!strcmp(id->name, "yx240qv29"))
> +		return ili9341_dbi_probe(spi);
> +
> +	return -1;
> +}
> +
> +static int ili9341_remove(struct spi_device *spi)
> +{
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +	struct ili9341 *ili = spi_get_drvdata(spi);
> +	struct drm_device *drm = spi_get_drvdata(spi);
> +
> +	if (!strcmp(id->name, "sf-tc240t-9370-t")) {
> +		ili9341_dpi_power_off(ili);
> +		drm_panel_remove(&ili->panel);
> +	} else if (!strcmp(id->name, "yx240qv29")) {
> +		drm_dev_unplug(drm);
> +		drm_atomic_helper_shutdown(drm);
> +	}
> +	return 0;
> +}
> +
> +static void ili9341_shutdown(struct spi_device *spi)
> +{
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +
> +	if (!strcmp(id->name, "yx240qv29"))
> +		drm_atomic_helper_shutdown(spi_get_drvdata(spi));
> +}
> +
> +static const struct of_device_id ili9341_of_match[] = {
> +	{
> +		.compatible = "st,sf-tc240t-9370-t",
> +		.data = &ili9341_stm32f429_disco_data,
> +	},
> +	{
> +		/* porting from tiny/ili9341.c
> +		 * for original mipi dbi compitable
> +		 */
> +		.compatible = "adafruit,yx240qv29",
> +		.data = NULL,
> +	},
> +};
> +MODULE_DEVICE_TABLE(of, ili9341_of_match);
> +
> +static const struct spi_device_id ili9341_id[] = {
> +	{ "yx240qv29", 0 },
> +	{ "sf-tc240t-9370-t", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, ili9341_id);
> +
> +static struct spi_driver ili9341_driver = {
> +	.probe = ili9341_probe,
> +	.remove = ili9341_remove,
> +	.shutdown = ili9341_shutdown,
> +	.id_table = ili9341_id,
> +	.driver = {
> +		.name = "panel-ilitek-ili9341",
> +		.of_match_table = ili9341_of_match,
> +	},
> +};
> +module_spi_driver(ili9341_driver);
> +
> +MODULE_AUTHOR("Dillon Min <dillon.minfei@gmail.com>");
> +MODULE_DESCRIPTION("ILI9341 LCD panel driver");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
                   ` (4 preceding siblings ...)
  2021-05-28  6:01 ` [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform Dillon Min
@ 2021-05-31 13:20 ` Patrice CHOTARD
  2021-05-31 13:38   ` Dillon Min
  5 siblings, 1 reply; 20+ messages in thread
From: Patrice CHOTARD @ 2021-05-31 13:20 UTC (permalink / raw)
  To: dillon.minfei, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, linux-stm32, linux-arm-kernel, linux-media

Hi Dillon



On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> From: Dillon Min <dillon.minfei@gmail.com>
> 
> This seriese fix three i2c/clk bug for stm32 f4/f7
> - kernel runing in sdram, i2c driver get data timeout
> - ltdc clk turn off after kernel console active
> - kernel hang in set ltdc clock rate
> 
> clk bug found on stm32f429/f469-disco board
> 
> Hi Patrice:
> below is the guide to verify the patch:
> 
> setup test env with following files(link at below 'files link'):
> [1] u-boot-dtb.bin
> [2] rootfs zip file (used in kernel initramfs)
> [3] u-boot's mkimage to create itb file
> [4] kernel config file
> [5] my itb with-or-without i2c patch
> 
> This patch based on kernel commit:
> 88b06399c9c766c283e070b022b5ceafa4f63f19
> 
> Note:
> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
> get accepted. it's used to setup touch screen calibration, then test i2c.
> 
> create itb file(please correct path of 'data'):
> ./mkimage -f stm32.its stm32.itb
> 
> HW setup:
> console:
>        PA9, PA10
>        usart0
>        serial@40011000
>        115200 8n1
> 
> -- flash u-boot.bin to stm32f429-disco on PC
> $ sudo openocd -f board/stm32f429discovery.cfg -c \
>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
> 
> -- setup kernel load bootargs at u-boot
> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
> U-Boot > loady;bootm
> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
> 


Thanks for these informations
I was able to load and boot DTB and uImage directly in SDRAM as you suggested, 
i saw Linux logo and kernel log on the STM32F429-disco display, 
but i can't reach the login.

The last kernel log i got is :

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
[    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: unknown data cache, unknown instruction cache
[    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges

[...]

[    2.637564] printk: console [ttySTM0] enabled
[    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
[    2.758986] spi_stm32 40015000.spi: driver initialized
[    2.795733] i2c /dev entries driver
[    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
[    2.922030] stmpe-ts stmpe-ts: DMA mask not set
[    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
[    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
[    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
[    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
[    3.765208] Console: switching to colour frame buffer device 30x40
[    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
[    4.212737] Freeing unused kernel memory: 324K
[    4.287300] This architecture does not have kernel memory protection.
[    4.401202] Run /linuxrc as init process
[    4.478622]   with arguments:
[    4.555069]     /linuxrc
[    4.595406]   with environment:
[    4.672213]     HOME=/
[    4.712511]     TERM=linux
[  206.785289] random: crng init done


I can't test your I2C patch.

Patrice


> -- setup ts_calibrate running env on stm32f429-disco
> / # export TSLIB_CONFFILE=/etc/ts.conf
> / # export TSLIB_TSDEVICE=/dev/input/event0
> / # export TSLIB_CONSOLEDEVICE=none
> / # export TSLIB_FBDEVICE=/dev/fb0
> 
> -- clear screen
> / # ./fb
> 
> -- run ts_calibrate 
> / # ts_calibrate
> (you can calibrate touchscreen now, and get below errors)
> 
> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
> 
> ...
> with i2c patch applied, you will find below logs:
> 
> RAW---------------------> 3164 908 183 118.110884
> TS_READ_RAW----> x = 3164, y =908, pressure = 183
> RAW---------------------> 3166 922 126 118.138946
> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
> ....
> 
> files link:
> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
> 
> 
> 
> 
> Dillon Min (4):
>   drm/panel: Add ilitek ili9341 panel driver
>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
>     kernel startup
> 
>  drivers/clk/clk-stm32f4.c                    |   10 +-
>  drivers/gpu/drm/panel/Kconfig                |   12 +
>  drivers/gpu/drm/panel/Makefile               |    1 +
>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
>  5 files changed, 1310 insertions(+), 10 deletions(-)
>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-31 13:20 ` Patrice CHOTARD
@ 2021-05-31 13:38   ` Dillon Min
  2021-05-31 13:50     ` Patrice CHOTARD
  0 siblings, 1 reply; 20+ messages in thread
From: Dillon Min @ 2021-05-31 13:38 UTC (permalink / raw)
  To: Patrice CHOTARD
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

Hi Patrice

Thanks for your time to test my patch.

On Mon, May 31, 2021 at 9:20 PM Patrice CHOTARD
<patrice.chotard@foss.st.com> wrote:
>
> Hi Dillon
>
>
>
> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> > From: Dillon Min <dillon.minfei@gmail.com>
> >
> > This seriese fix three i2c/clk bug for stm32 f4/f7
> > - kernel runing in sdram, i2c driver get data timeout
> > - ltdc clk turn off after kernel console active
> > - kernel hang in set ltdc clock rate
> >
> > clk bug found on stm32f429/f469-disco board
> >
> > Hi Patrice:
> > below is the guide to verify the patch:
> >
> > setup test env with following files(link at below 'files link'):
> > [1] u-boot-dtb.bin
> > [2] rootfs zip file (used in kernel initramfs)
> > [3] u-boot's mkimage to create itb file
> > [4] kernel config file
> > [5] my itb with-or-without i2c patch
> >
> > This patch based on kernel commit:
> > 88b06399c9c766c283e070b022b5ceafa4f63f19
> >
> > Note:
> > panel-ilitek-ili9341.c is the driver which was submitted last year, but not
> > get accepted. it's used to setup touch screen calibration, then test i2c.
> >
> > create itb file(please correct path of 'data'):
> > ./mkimage -f stm32.its stm32.itb
> >
> > HW setup:
> > console:
> >        PA9, PA10
> >        usart0
> >        serial@40011000
> >        115200 8n1
> >
> > -- flash u-boot.bin to stm32f429-disco on PC
> > $ sudo openocd -f board/stm32f429discovery.cfg -c \
> >   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
> >
> > -- setup kernel load bootargs at u-boot
> > U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
> >                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
> > U-Boot > loady;bootm
> > (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
> >
>
>
> Thanks for these informations
> I was able to load and boot DTB and uImage directly in SDRAM as you suggested,
> i saw Linux logo and kernel log on the STM32F429-disco display,
> but i can't reach the login.
>
> The last kernel log i got is :
>
> Starting kernel ...
>
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
> [    0.000000] CPU: unknown data cache, unknown instruction cache
> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
> [    0.000000] Zone ranges:
> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
> [    0.000000] Movable zone start for each node
> [    0.000000] Early memory node ranges
>
> [...]
>
> [    2.637564] printk: console [ttySTM0] enabled
> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
> [    2.758986] spi_stm32 40015000.spi: driver initialized
> [    2.795733] i2c /dev entries driver
> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
> [    3.765208] Console: switching to colour frame buffer device 30x40
> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
> [    4.212737] Freeing unused kernel memory: 324K
> [    4.287300] This architecture does not have kernel memory protection.
> [    4.401202] Run /linuxrc as init process
> [    4.478622]   with arguments:
> [    4.555069]     /linuxrc
> [    4.595406]   with environment:
> [    4.672213]     HOME=/
> [    4.712511]     TERM=linux
> [  206.785289] random: crng init done

I guess you didn't add the rootfs to uImage I sent you.
Could you post all the logs from u-boot startup to kernel log end.

If possible, you can try my suggestion.
- tar -jxf stm32_rootfs.tar.bz2
- add stm32_rootfs to your kernel config( enable initramfs)
- make O=YOUR_KERNEL_OUT zImage dtbs LOADADDR=0x90008000
- create itb file (combine dtb and kernel, initramfs) by mkimage
  ./mkimage -f stm32.its stm32.itb
  (before above command, make sure you correct stm32.its adapt to your env)

This process will make u-boot to load the kernel more simple.

Thanks.

Best Regards.
Dillon


>
>
> I can't test your I2C patch.
>
> Patrice
>
>
> > -- setup ts_calibrate running env on stm32f429-disco
> > / # export TSLIB_CONFFILE=/etc/ts.conf
> > / # export TSLIB_TSDEVICE=/dev/input/event0
> > / # export TSLIB_CONSOLEDEVICE=none
> > / # export TSLIB_FBDEVICE=/dev/fb0
> >
> > -- clear screen
> > / # ./fb
> >
> > -- run ts_calibrate
> > / # ts_calibrate
> > (you can calibrate touchscreen now, and get below errors)
> >
> > [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
> > [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
> > [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
> > [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
> >
> > ...
> > with i2c patch applied, you will find below logs:
> >
> > RAW---------------------> 3164 908 183 118.110884
> > TS_READ_RAW----> x = 3164, y =908, pressure = 183
> > RAW---------------------> 3166 922 126 118.138946
> > TS_READ_RAW----> x = 3166, y = 922, pressure = 126
> > ....
> >
> > files link:
> > https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
> >
> >
> >
> >
> > Dillon Min (4):
> >   drm/panel: Add ilitek ili9341 panel driver
> >   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
> >   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
> >   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
> >     kernel startup
> >
> >  drivers/clk/clk-stm32f4.c                    |   10 +-
> >  drivers/gpu/drm/panel/Kconfig                |   12 +
> >  drivers/gpu/drm/panel/Makefile               |    1 +
> >  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
> >  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
> >  5 files changed, 1310 insertions(+), 10 deletions(-)
> >  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> >

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver
  2021-05-31 13:15   ` Patrice CHOTARD
@ 2021-05-31 13:39     ` Dillon Min
  2021-06-01  2:31       ` Dillon Min
  0 siblings, 1 reply; 20+ messages in thread
From: Dillon Min @ 2021-05-31 13:39 UTC (permalink / raw)
  To: Patrice CHOTARD
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

On Mon, May 31, 2021 at 9:15 PM Patrice CHOTARD
<patrice.chotard@foss.st.com> wrote:
>
> Hi Dillon
>
> When trying to applying this patch using "git am --3 <patch>"  i got this error :
>
> error: cannot convert from y to UTF-8
> fatal: could not parse patch
>
> Whereas i got no similar error with the other patch 2/3 and 4.
>
> I find a way to apply it anyway.

Sorry for the inconvenience, I will double verify the 'git am' process
on this patch later.

Thanks.

Best Regards
Dillon

>
> Patrice
>
>
> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> > From: Dillon Min <dillon.minfei@gmail.com>
> >
> > This driver combine tiny/ili9341.c mipi_dbi_interface driver
> > with mipi_dpi_interface driver, can support ili9341 with serial
> > mode or parallel rgb interface mode by register configuration.
> >
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > Link: https://lore.kernel.org/lkml/1590378348-8115-7-git-send-email-dillon.minfei@gmail.com/
> > Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> > ---
> >  drivers/gpu/drm/panel/Kconfig                |   12 +
> >  drivers/gpu/drm/panel/Makefile               |    1 +
> >  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
> >  3 files changed, 1298 insertions(+)
> >  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> >
> > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> > index 4894913936e9..e4babba17864 100644
> > --- a/drivers/gpu/drm/panel/Kconfig
> > +++ b/drivers/gpu/drm/panel/Kconfig
> > @@ -123,6 +123,18 @@ config DRM_PANEL_ILITEK_IL9322
> >         Say Y here if you want to enable support for Ilitek IL9322
> >         QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
> >
> > +config DRM_PANEL_ILITEK_ILI9341
> > +     tristate "Ilitek ILI9341 240x320 QVGA panels"
> > +     depends on OF && SPI
> > +     depends on DRM_KMS_HELPER
> > +     depends on DRM_KMS_CMA_HELPER
> > +     depends on BACKLIGHT_CLASS_DEVICE
> > +     select DRM_MIPI_DBI
> > +     help
> > +       Say Y here if you want to enable support for Ilitek IL9341
> > +       QVGA (240x320) RGB panels. support serial & parallel rgb
> > +       interface.
> > +
> >  config DRM_PANEL_ILITEK_ILI9881C
> >       tristate "Ilitek ILI9881C-based panels"
> >       depends on OF
> > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> > index cae4d976c069..0ecde184665d 100644
> > --- a/drivers/gpu/drm/panel/Makefile
> > +++ b/drivers/gpu/drm/panel/Makefile
> > @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
> >  obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
> >  obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
> >  obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
> > +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
> >  obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
> >  obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
> >  obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
> > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > new file mode 100644
> > index 000000000000..f84983cbb250
> > --- /dev/null
> > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > @@ -0,0 +1,1285 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Ilitek ILI9341 TFT LCD drm_panel driver.
> > + *
> > + * This panel can be configured to support:
> > + * - 16-bit parallel RGB interface
> > + * - 18-bit parallel RGB interface
> > + * - 4-line serial spi interface
> > + *
> > + * Copyright (C) 2020 Dillon Min <dillon.minfei@gmail.com>
> > + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
> > + */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <linux/spi/spi.h>
> > +#include <linux/delay.h>
> > +#include <video/mipi_display.h>
> > +#include <drm/drm_mipi_dbi.h>
> > +#include <drm/drm_gem_framebuffer_helper.h>
> > +#include <drm/drm_gem_cma_helper.h>
> > +#include <drm/drm_fb_helper.h>
> > +#include <drm/drm_gem_atomic_helper.h>
> > +#include <drm/drm_atomic_helper.h>
> > +
> > +#include <drm/drm_drv.h>
> > +#include <drm/drm_modes.h>
> > +#include <drm/drm_panel.h>
> > +#include <drm/drm_print.h>
> > +
> > +#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
> > +#define ILI9341_FRC            0xb1   /* Frame Rate Control register */
> > +#define ILI9341_DFC            0xb6   /* Display Function Control register */
> > +#define ILI9341_POWER1         0xc0   /* Power Control 1 register */
> > +#define ILI9341_POWER2         0xc1   /* Power Control 2 register */
> > +#define ILI9341_VCOM1          0xc5   /* VCOM Control 1 register */
> > +#define ILI9341_VCOM2          0xc7   /* VCOM Control 2 register */
> > +#define ILI9341_POWERA         0xcb   /* Power control A register */
> > +#define ILI9341_POWERB         0xcf   /* Power control B register */
> > +#define ILI9341_PGAMMA         0xe0   /* Positive Gamma Correction register */
> > +#define ILI9341_NGAMMA         0xe1   /* Negative Gamma Correction register */
> > +#define ILI9341_DTCA           0xe8   /* Driver timing control A */
> > +#define ILI9341_DTCB           0xea   /* Driver timing control B */
> > +#define ILI9341_POWER_SEQ      0xed   /* Power on sequence register */
> > +#define ILI9341_3GAMMA_EN      0xf2   /* 3 Gamma enable register */
> > +#define ILI9341_INTERFACE      0xf6   /* Interface control register */
> > +#define ILI9341_PRC            0xf7   /* Pump ratio control register */
> > +#define ILI9341_ETMOD               0xb7   /* Entry mode set */
> > +
> > +#define ILI9341_MADCTL_BGR   BIT(3)
> > +#define ILI9341_MADCTL_MV    BIT(5)
> > +#define ILI9341_MADCTL_MX    BIT(6)
> > +#define ILI9341_MADCTL_MY    BIT(7)
> > +
> > +
> > +#define ILI9341_POWER_B_LEN  3
> > +#define ILI9341_POWER_SEQ_LEN        4
> > +#define ILI9341_DTCA_LEN     3
> > +#define ILI9341_DTCB_LEN     2
> > +#define ILI9341_POWER_A_LEN  5
> > +#define ILI9341_DFC_1_LEN    2
> > +#define ILI9341_FRC_LEN              2
> > +#define ILI9341_VCOM_1_LEN   2
> > +#define ILI9341_DFC_2_LEN    4
> > +#define ILI9341_COLUMN_ADDR_LEN      4
> > +#define ILI9341_PAGE_ADDR_LEN        4
> > +#define ILI9341_INTERFACE_LEN        3
> > +#define ILI9341_PGAMMA_LEN   15
> > +#define ILI9341_NGAMMA_LEN   15
> > +#define ILI9341_CA_LEN               3
> > +
> > +#define ILI9341_PIXEL_DPI_16_BITS    (BIT(6)|BIT(4))
> > +#define ILI9341_PIXEL_DPI_18_BITS    (BIT(6)|BIT(5))
> > +#define ILI9341_GAMMA_CURVE_1                BIT(0)
> > +#define ILI9341_IF_WE_MODE           BIT(0)
> > +#define ILI9341_IF_BIG_ENDIAN                0x00
> > +#define ILI9341_IF_DM_RGB            BIT(2)
> > +#define ILI9341_IF_DM_INTERNAL               0x00
> > +#define ILI9341_IF_DM_VSYNC          BIT(3)
> > +#define ILI9341_IF_RM_RGB            BIT(1)
> > +#define ILI9341_IF_RIM_RGB           0x00
> > +
> > +#define ILI9341_COLUMN_ADDR          0x00ef
> > +#define ILI9341_PAGE_ADDR            0x013f
> > +
> > +#define ILI9341_RGB_EPL                      BIT(0)
> > +#define ILI9341_RGB_DPL                      BIT(1)
> > +#define ILI9341_RGB_HSPL             BIT(2)
> > +#define ILI9341_RGB_VSPL             BIT(3)
> > +#define ILI9341_RGB_DE_MODE          BIT(6)
> > +#define ILI9341_RGB_DISP_PATH_MEM    BIT(7)
> > +
> > +#define ILI9341_DBI_VCOMH_4P6V               0x23
> > +#define ILI9341_DBI_PWR_2_DEFAULT    0x10
> > +#define ILI9341_DBI_PRC_NORMAL               0x20
> > +#define ILI9341_DBI_VCOM_1_VMH_4P25V 0x3e
> > +#define ILI9341_DBI_VCOM_1_VML_1P5V  0x28
> > +#define ILI9341_DBI_VCOM_2_DEC_58    0x86
> > +#define ILI9341_DBI_FRC_DIVA         0x00
> > +#define ILI9341_DBI_FRC_RTNA         0x1b
> > +#define ILI9341_DBI_EMS_GAS          BIT(0)
> > +#define ILI9341_DBI_EMS_DTS          BIT(1)
> > +#define ILI9341_DBI_EMS_GON          BIT(2)
> > +/**
> > + * ili9341_command - ili9341 command with optional parameter(s)
> > + * @ili: struct ili9341
> > + * @cmd: Command
> > + * @seq...: Optional parameter(s)
> > + *
> > + * Send command to the controller.
> > + *
> > + * Returns:
> > + * Zero on success, negative error code on failure.
> > + */
> > +#define ili9341_command(ili, cmd, seq...) \
> > +({ \
> > +     u8 d[] = { seq }; \
> > +     _ili9341_command(ili, cmd, d, ARRAY_SIZE(d)); \
> > +})
> > +
> > +/**
> > + * struct ili9341_config - the system specific ILI9341 configuration
> > + * @max_spi_speed: 10000000
> > + */
> > +struct ili9341_config {
> > +     u32 max_spi_speed;
> > +     /** @mode: the drm display mode */
> > +     const struct drm_display_mode mode;
> > +     /** @ca: TODO: need comments for this register */
> > +     u8 ca[ILI9341_CA_LEN];
> > +     /** @power_b: TODO: need comments for this register */
> > +     u8 power_b[ILI9341_POWER_B_LEN];
> > +     /** @power_seq: TODO: need comments for this register */
> > +     u8 power_seq[ILI9341_POWER_SEQ_LEN];
> > +     /** @dtca: TODO: need comments for this register */
> > +     u8 dtca[ILI9341_DTCA_LEN];
> > +     /** @dtcb: TODO: need comments for this register */
> > +     u8 dtcb[ILI9341_DTCB_LEN];
> > +     /** @power_a: TODO: need comments for this register */
> > +     u8 power_a[ILI9341_POWER_A_LEN];
> > +     /** @frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
> > +     /*
> > +      * Formula to calculate frame frequency:
> > +      * Frame Rate=fosc/(Clocks per line x Division ratio x
> > +      * (Lines+VBP+VFP))
> > +      *
> > +      * Sets the division ratio for internal clocks of Normal mode at MCU
> > +      * interface.
> > +      *
> > +      * fosc : internal oscillator frequency
> > +      * Clocks per line : RTNA setting
> > +      * Division ratio : DIVA setting
> > +      * Lines : total driving line number
> > +      * VBP : back porch line number
> > +      * VFP : front porch line number
> > +      *
> > +      * RTNA [4:0] Frame Rate (Hz)   RTNA [4:0] Frame Rate (Hz)
> > +      * 1 0 0 0 0  119               1 1 0 0 0  79
> > +      * 1 0 0 0 1  112               1 1 0 0 1  76
> > +      * 1 0 0 1 0  106               1 1 0 1 0  73
> > +      * 1 0 0 1 1  100               1 1 0 1 1  70(default)
> > +      * 1 0 1 0 0  95                1 1 1 0 0  68
> > +      * 1 0 1 0 1  90                1 1 1 0 1  65
> > +      * 1 0 1 1 0  86                1 1 1 0 1  63
> > +      * 1 0 1 1 1  83                1 1 1 1 1  61
> > +      *
> > +      * DIVA [1:0] : division ratio for internal clocks when Normal mode.
> > +      *
> > +      * DIVA [1:0] Division Ratio
> > +      * 0 0 fosc
> > +      * 0 1 fosc / 2
> > +      * 1 0 fosc / 4
> > +      * 1 1 fosc / 8
> > +      *
> > +      */
> > +     u8 frc[ILI9341_FRC_LEN];
> > +     /** @prc: TODO: need comments for this register */
> > +     u8 prc;
> > +     /** @dfc_1: B6h DISCTRL (Display Function Control) */
> > +     /*               D/CX RDX WRX D17-8 D7  D6 D5 D4 D3   D2  D1  D0  HEX
> > +      * Command       0    1   M   XX    1   0  1  1  0    1   1   0   B6h
> > +      * 1st Parameter 1    1   M   XX    0   0  0  0  PTG[1:0] PT[1:0] 0A
> > +      * 2nd Parameter 1    1   M   XX    REV GS SS SM ISC[3:0]         82
> > +      * 3rd Parameter 1    1   M   XX    0   0  NL[5:0]                27
> > +      * 4th Parameter 1    1   M   XX    0   0  PCDIV[5:0]             XX
> > +      *
> > +      * PTG [1:0]: Set the scan mode in non-display area.
> > +      * PTG1 | PTG0 | Gate outputs in   | Source outputs in  | VCOM output
> > +      *               non-display area  | non-display area   |
> > +      * 1      0      Interval scan       Set with the PT[2:0] bits
> > +      *
> > +      * PT [1:0]: Determine source/VCOM output in a non-display area in the
> > +      * partial display mode.
> > +      * 1    0    AGND       AGND       AGND         AGND
> > +      *
> > +      * REV: Select whether the liquid crystal type is normally white type
> > +      * or normally black type.
> > +      * REV   Liquid crystal type
> > +      * 0     Normally black
> > +      * 1     Normally white
> > +      *
> > +      * SS: Select the shift direction of outputs from the source driver.
> > +      * SS    Source Output Scan Direction
> > +      * 0     S1 -> S720
> > +      * 1     S720 -> S1
> > +      *
> > +      * GS: Sets the direction of scan by the gate driver in the range
> > +      * determined by SCN [4:0] and NL [4:0]. The scan direction
> > +      * determined by GS = 0 can be reversed by setting GS = 1.
> > +      *
> > +      * GS     Gate Output Scan Direction
> > +      * 0      G1 -> G320
> > +      * 1      G320 -> G1
> > +      */
> > +     u8 dfc_1[ILI9341_DFC_1_LEN];
> > +      /** @power_1: Power Control 1 (C0h) */
> > +      /* VRH [5:0]: Set the GVDD level, which is a reference level for the
> > +      * VCOM level and the grayscale voltage level.
> > +      *
> > +      * VRH[5:0]    GVDD                     VRH[5:0]        GVDD
> > +      * 0 0 0 0 0 0 Setting prohibited       1 0 0 0 0 0     4.45 V
> > +      * 0 0 0 0 0 1 Setting prohibited       1 0 0 0 0 1     4.50 V
> > +      * 0 0 0 0 1 0 Setting prohibited       1 0 0 0 1 0     4.55 V
> > +      * 0 0 0 0 1 1 3.00 V                   1 0 0 0 1 1     4.60 V
> > +      * 0 0 0 1 0 0 3.05 V                   1 0 0 1 0 0     4.65 V
> > +      * 0 0 0 1 0 1 3.10 V                   1 0 0 1 0 1     4.70 V
> > +      * 0 0 0 1 1 0 3.15 V                   1 0 0 1 1 0     4.75 V
> > +      * 0 0 0 1 1 1 3.20 V                   1 0 0 1 1 1     4.80 V
> > +      * 0 0 1 0 0 0 3.25 V                   1 0 1 0 0 0     4.85 V
> > +      * 0 0 1 0 0 1 3.30 V                   1 0 1 0 0 1     4.90 V
> > +      * 0 0 1 0 1 0 3.35 V                   1 0 1 0 1 0     4.95 V
> > +      * 0 0 1 0 1 1 3.40 V                   1 0 1 0 1 1     5.00 V
> > +      * 0 0 1 1 0 0 3.45 V                   1 0 1 1 0 0     5.05 V
> > +      * 0 0 1 1 0 1 3.50 V                   1 0 1 1 0 1     5.10 V
> > +      * 0 0 1 1 1 0 3.55 V                   1 0 1 1 1 0     5.15 V
> > +      * 0 0 1 1 1 1 3.60 V                   1 0 1 1 1 1     5.20 V
> > +      * 0 1 0 0 0 0 3.65 V                   1 1 0 0 0 0     5.25 V
> > +      * 0 1 0 0 0 1 3.70 V                   1 1 0 0 0 1     5.30 V
> > +      * 0 1 0 0 1 0 3.75 V                   1 1 0 0 1 0     5.35 V
> > +      * 0 1 0 0 1 1 3.80 V                   1 1 0 0 1 1     5.40 V
> > +      * 0 1 0 1 0 0 3.85 V                   1 1 0 1 0 0     5.45 V
> > +      * 0 1 0 1 0 1 3.90 V                   1 1 0 1 0 1     5.50 V
> > +      * 0 1 0 1 1 0 3.95 V                   1 1 0 1 1 0     5.55 V
> > +      * 0 1 0 1 1 1 4.00 V                   1 1 0 1 1 1     5.60 V
> > +      * 0 1 1 0 0 0 4.05 V                   1 1 1 0 0 0     5.65 V
> > +      * 0 1 1 0 0 1 4.10 V                   1 1 1 0 0 1     5.70 V
> > +      * 0 1 1 0 1 0 4.15 V                   1 1 1 0 1 0     5.75 V
> > +      * 0 1 1 0 1 1 4.20 V                   1 1 1 0 1 1     5.80 V
> > +      * 0 1 1 1 0 0 4.25 V                   1 1 1 1 0 0     5.85 V
> > +      * 0 1 1 1 0 1 4.30 V                   1 1 1 1 0 1     5.90 V
> > +      * 0 1 1 1 1 0 4.35 V                   1 1 1 1 1 0     5.95 V
> > +      * 0 1 1 1 1 1 4.40 V                   1 1 1 1 1 1     6.00 V
> > +      */
> > +     u8 power_1;
> > +     /** @power_2: Power Control 2 (C1h) */
> > +     /*
> > +      * BT [2:0]: Sets the factor used in the step-up circuits.
> > +      * Select the optimal step-up factor for the operating voltage. To
> > +      * reduce power consumption, set a smaller factor.
> > +      *
> > +      * BT[2:0]   AVDD     VGH      VGL
> > +      * 0 0 0     VCI x 2  VCI x 7  VCI x 4
> > +      * 0 0 1                       VCI x 3
> > +      * 0 1 0              VCI x 6  VCI x 4
> > +      * 0 1 1                       VCI x 3
> > +      *
> > +      */
> > +     u8 power_2;
> > +     /** @vcom_1: VCOM Control 1(C5h) */
> > +     /*
> > +      * VMH [6:0] : Set the VCOMH voltage
> > +      *
> > +      * VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH
> > +      * 0000000  2.700    0100000  3.500    1000000  4.300    1100000  5.100
> > +      * 0000001  2.725    0100001  3.525    1000001  4.325    1100001  5.125
> > +      * 0000010  2.750    0100010  3.550    1000010  4.350    1100010  5.150
> > +      * 0000011  2.775    0100011  3.575    1000011  4.375    1100011  5.175
> > +      * 0000100  2.800    0100100  3.600    1000100  4.400    1100100  5.200
> > +      * 0000101  2.825    0100101  3.625    1000101  4.425    1100101  5.225
> > +      * 0000110  2.850    0100110  3.650    1000110  4.450    1100110  5.250
> > +      * 0000111  2.875    0100111  3.675    1000111  4.475    1100111  5.275
> > +      * 0001000  2.900    0101000  3.700    1001000  4.500    1101000  5.300
> > +      * 0001001  2.925    0101001  3.725    1001001  4.525    1101001  5.325
> > +      * 0001010  2.950    0101010  3.750    1001010  4.550    1101010  5.350
> > +      * 0001011  2.975    0101011  3.775    1001011  4.575    1101011  5.375
> > +      * 0001100  3.000    0101100  3.800    1001100  4.600    1101100  5.400
> > +      * 0001101  3.025    0101101  3.825    1001101  4.625    1101101  5.425
> > +      * 0001110  3.050    0101110  3.850    1001110  4.650    1101110  5.450
> > +      * 0001111  3.075    0101111  3.875    1001111  4.675    1101111  5.475
> > +      * 0010000  3.100    0110000  3.900    1010000  4.700    1110000  5.500
> > +      * 0010001  3.125    0110001  3.925    1010001  4.725    1110001  5.525
> > +      * 0010010  3.150    0110010  3.950    1010010  4.750    1110010  5.550
> > +      * 0010011  3.175    0110011  3.975    1010011  4.775    1110011  5.575
> > +      * 0010100  3.200    0110100  4.000    1010100  4.800    1110100  5.600
> > +      * 0010101  3.225    0110101  4.025    1010101  4.825    1110101  5.625
> > +      * 0010110  3.250    0110110  4.050    1010110  4.850    1110110  5.650
> > +      * 0010111  3.275    0110111  4.075    1010111  4.875    1110111  5.675
> > +      * 0011000  3.300    0111000  4.100    1011000  4.900    1111000  5.700
> > +      * 0011001  3.325    0111001  4.125    1011001  4.925    1111001  5.725
> > +      * 0011010  3.350    0111010  4.150    1011010  4.950    1111010  5.750
> > +      * 0011011  3.375    0111011  4.175    1011011  4.975    1111011  5.775
> > +      * 0011100  3.400    0111100  4.200    1011100  5.000    1111100  5.800
> > +      * 0011101  3.425    0111101  4.225    1011101  5.025    1111101  5.825
> > +      * 0011110  3.450    0111110  4.250    1011110  5.050    1111110  5.850
> > +      * 0011111  3.475    0111111  4.275    1011111  5.075    1111111  5.875
> > +      *
> > +      * VML[6:0] : Set the VCOML voltage
> > +      *
> > +      * VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML
> > +      * 0000000 -2.500 0100000 -1.700 1000000 -0.900 1100000 -0.100
> > +      * 0000001 -2.475 0100001 -1.675 1000001 -0.875 1100001 -0.075
> > +      * 0000010 -2.450 0100010 -1.650 1000010 -0.850 1100010 -0.050
> > +      * 0000011 -2.425 0100011 -1.625 1000011 -0.825 1100011 -0.025
> > +      * 0000100 -2.400 0100100 -1.600 1000100 -0.800 1100100 0
> > +      * 0000101 -2.375 0100101 -1.575 1000101 -0.775 1100101 Reserved
> > +      * 0000110 -2.350 0100110 -1.550 1000110 -0.750 1100110 Reserved
> > +      * 0000111 -2.325 0100111 -1.525 1000111 -0.725 1100111 Reserved
> > +      * 0001000 -2.300 0101000 -1.500 1001000 -0.700 1101000 Reserved
> > +      * 0001001 -2.275 0101001 -1.475 1001001 -0.675 1101001 Reserved
> > +      * 0001010 -2.250 0101010 -1.450 1001010 -0.650 1101010 Reserved
> > +      * 0001011 -2.225 0101011 -1.425 1001011 -0.625 1101011 Reserved
> > +      * 0001100 -2.200 0101100 -1.400 1001100 -0.600 1101100 Reserved
> > +      * 0001101 -2.175 0101101 -1.375 1001101 -0.575 1101101 Reserved
> > +      * 0001110 -2.150 0101110 -1.350 1001110 -0.550 1101110 Reserved
> > +      * 0001111 -2.125 0101111 -1.325 1001111 -0.525 1101111 Reserved
> > +      * 0010000 -2.100 0110000 -1.300 1010000 -0.500 1110000 Reserved
> > +      * 0010001 -2.075 0110001 -1.275 1010001 -0.475 1110001 Reserved
> > +      * 0010010 -2.050 0110010 -1.250 1010010 -0.450 1110010 Reserved
> > +      * 0010011 -2.025 0110011 -1.225 1010011 -0.425 1110011 Reserved
> > +      * 0010100 -2.000 0110100 -1.200 1010100 -0.400 1110100 Reserved
> > +      * 0010101 -1.975 0110101 -1.175 1010101 -0.375 1110101 Reserved
> > +      * 0010110 -1.950 0110110 -1.150 1010110 -0.350 1110110 Reserved
> > +      * 0010111 -1.925 0110111 -1.125 1010111 -0.325 1110111 Reserved
> > +      * 0011000 -1.900 0111000 -1.100 1011000 -0.300 1111000 Reserved
> > +      * 0011001 -1.875 0111001 -1.075 1011001 -0.275 1111001 Reserved
> > +      * 0011010 -1.850 0111010 -1.050 1011010 -0.250 1111010 Reserved
> > +      * 0011011 -1.825 0111011 -1.025 1011011 -0.225 1111011 Reserved
> > +      * 0011100 -1.800 0111100 -1.000 1011100 -0.200 1111100 Reserved
> > +      * 0011101 -1.775 0111101 -0.975 1011101 -0.175 1111101 Reserved
> > +      * 0011110 -1.750 0111110 -0.950 1011110 -0.150 1111110 Reserved
> > +      * 0011111 -1.725 0111111 -0.925 1011111 -0.125 1111111 Reserved
> > +      */
> > +     u8 vcom_1[ILI9341_VCOM_1_LEN];
> > +     /** @vcom_2: VCOM Control 2(C7h) */
> > +     /*
> > +      * C7h          VMCTRL1 (VCOM Control 1)
> > +      *              D/CX RDX WRX D17-8 D7  D6  D5 D4 D3 D2 D1 D0 HEX
> > +      * Command      0    1   M   XX    1   1   0  0  0  1  1  1  C7h
> > +      * Parameter    1    1   M   XX    nVM VMF[6:0]              C0
> > +      *
> > +      * nVM: nVM equals to “0” after power on reset and VCOM offset
> > +      * equals to program MTP value. When nVM set to “1”, setting
> > +      * of VMF [6:0] becomes valid and VCOMH/VCOML can be adjusted.
> > +      *
> > +      * VMF [6:0]: Set the VCOM offset voltage.
> > +      */
> > +     u8 vcom_2;
> > +     /** @address_mode: Memory Access Control (36h) */
> > +     /*
> > +      * 36h          MADCTL (Memory Access Control)
> > +      *              D/CX RDX WRX D17-8 D7 D6 D5 D4 D3  D2 D1 D0 HEX
> > +      * Command      0    1   M   XX    0  0  1  1  0   1  1  0  36h
> > +      * Parameter    1    1   M   XX    MY MX MV ML BGR MH 0  0  00
> > +      *
> > +      * This command defines read/write scanning direction of frame memory.
> > +      * This command makes no change on the other driver status.
> > +      *
> > +      * Bit  Name                     Description
> > +      * MY   Row Address Order
> > +      * MX   Column Address Order
> > +      * MV   Row / Column Exchange    These 3 bits control MCU to memory
> > +      *                               write/read direction.
> > +      * ML   Vertical Refresh Order   LCD vertical refresh direction control.
> > +      * BGR  RGB-BGR Order            Color selector switch control
> > +      *                               (0=RGB color filter panel, 1=BGR
> > +      *                               color filter panel)
> > +      * MH   Horizontal Refresh ORDER LCD horizontal refreshing
> > +      * direction control.
> > +      *
> > +      * Note: When BGR bit is changed, the new setting is active
> > +      * immediately without update the content in Frame Memory again.
> > +      *
> > +      */
> > +     u8 address_mode;
> > +     /** @g3amma_en: TODO: need comments for this register */
> > +     u8 g3amma_en;
> > +     /** @rgb_interface: RGB Interface Signal Control (B0h) */
> > +     /*
> > +      * B0h          IFMODE (Interface Mode Control)
> > +      *              D/CX RDX WRX D17-8 D7          D6     D5     D4 D3   D2   D1  D0  HEX
> > +      * Command      0    1   M   XX    1           0      1      1  0    0    0   0   B0h
> > +      * Parameter    1    1   M   XX    ByPass_MODE RCM[1] RCM[0] 0  VSPL HSPL DPL EPL 40
> > +      *
> > +      * Sets the operation status of the display interface. The setting
> > +      * becomes effective as soon as the command is received.
> > +      * EPL: DE polarity (“0”= High enable for RGB interface, “1”= Low
> > +      * enable for RGB interface)
> > +      *
> > +      * DPL: DOTCLK polarity set (“0”= data fetched at the rising time,
> > +      * “1”= data fetched at the falling time)
> > +      *
> > +      * HSPL: HSYNC polarity (“0”= Low level sync clock, “1”= High
> > +      * level sync clock)
> > +      *
> > +      * VSPL: VSYNC polarity (“0”= Low level sync clock, “1”= High
> > +      * level sync clock)
> > +      *
> > +      * RCM [1:0]: RGB interface selection (refer to the RGB interface
> > +      * section).
> > +      *
> > +      * ByPass_MODE: Select display data path whether Memory or Direct to
> > +      * Shift register when RGB Interface is used.
> > +      *
> > +      * ByPass_MODE  Display Data Path
> > +      * 0            Direct to Shift Register (default)
> > +      * 1            Memory
> > +      */
> > +     u8 rgb_interface;
> > +     /** @dfc_2: refer to dfc_1 */
> > +     u8 dfc_2[ILI9341_DFC_2_LEN];
> > +     /** @column_addr: Column Address Set (2Ah) */
> > +     /* This command is used to define area of frame memory where MCU can
> > +      * access. This command makes no change on the
> > +      * other driver status. The values of SC [15:0] and EC [15:0] are
> > +      * referred when RAMWR command comes. Each value
> > +      * represents one column line in the Frame Memory.
> > +      */
> > +     u8 column_addr[ILI9341_COLUMN_ADDR_LEN];
> > +     /** @page_addr: Page Address Set (2Bh) */
> > +     /* This command is used to define area of frame memory where MCU can
> > +      * access. This command makes no change on the
> > +      * other driver status. The values of SP [15:0] and EP [15:0] are
> > +      * referred when RAMWR command comes. Each value
> > +      * represents one Page line in the Frame Memory.
> > +      */
> > +     u8 page_addr[ILI9341_PAGE_ADDR_LEN];
> > +     /** @interface: Interface Control (F6h) */
> > +     /*
> > +      * F6h          IFCTL (16bits Data Format Selection)
> > +      *              D/CX RDX WRX D17-8 D7   D6   D5     D4     D3      D2     D1     D0      HEX
> > +      * Command      0    1   M   XX    1    1    1      1      0       1      1      0       F6h
> > +      * 1stParameter 1    1   M   XX    MY   MX   MV
> > +      *                                 _EOR _EOR _EOR   0      BGR_EOR 0      0      WE MODE 01
> > +      * 2ndParameter 1    1   M   XX    0    0    EPF[1] EPF[0] 0       0      MDT[1] MDT[0]  00
> > +      * 3rdParameter 1    1   M   XX    0    0    ENDIAN 0      DM[1]   DM[0]  RM     RIM     00
> > +      *
> > +      */
> > +     u8 interface[ILI9341_INTERFACE_LEN];
> > +     /** @pixel_format: This command sets the pixel format for the RGB image data used by */
> > +     /* the interface. DPI [2:0] is the pixel format select of RGB
> > +      * interface and DBI [2:0] is the pixel format of MCU interface. If a
> > +      * particular interface, either RGB interface or MCU interface, is
> > +      * not used then the corresponding bits in the parameter are ignored.
> > +      * The pixel format is shown in the table below.
> > +      *
> > +      * DPI[2:0]     RGB Interface Format    DBI[2:0] MCU Interface Format
> > +      * 0 0 0        Reserved                0 0 0    Reserved
> > +      * 0 0 1        Reserved                0 0 1    Reserved
> > +      * 0 1 0        Reserved                0 1 0    Reserved
> > +      * 0 1 1        Reserved                0 1 1    Reserved
> > +      * 1 0 0        Reserved                1 0 0    Reserved
> > +      * 1 0 1        16 bits / pixel         1 0 1    16 bits / pixel
> > +      * 1 1 0        18 bits / pixel         1 1 0    18 bits / pixel
> > +      * 1 1 1        Reserved                1 1 1    Reserved
> > +      *
> > +      */
> > +     u8 pixel_format;
> > +     /** @gamma_curve: This command is used to select the desired Gamma curve for the */
> > +     /* current display. A maximum of 4 fixed gamma curves can
> > +      * be selected. The curve is selected by setting the appropriate bit
> > +      * in the parameter as described in the Table:
> > +      *
> > +      * GC [7:0]     Curve Selected
> > +      * 01h          Gamma curve 1 (G2.2)
> > +      * 02h          ---
> > +      * 04h          ---
> > +      * 08h          ---
> > +      */
> > +     u8 gamma_curve;
> > +     /** @pgamma: Positive Gamma Correction (E0h) */
> > +     /*
> > +      * Set the gray scale voltage to adjust the gamma characteristics of
> > +      * the TFT panel.
> > +      */
> > +     u8 pgamma[ILI9341_PGAMMA_LEN];
> > +     /** @ngamma: Negative Gamma Correction (E1h) */
> > +     /*
> > +      * Set the gray scale voltage to adjust the gamma characteristics of
> > +      * the TFT panel.
> > +      */
> > +     u8 ngamma[ILI9341_NGAMMA_LEN];
> > +};
> > +
> > +struct ili9341 {
> > +     struct device *dev;
> > +     const struct ili9341_config *conf;
> > +     struct drm_panel panel;
> > +     struct gpio_desc *reset_gpio;
> > +     struct gpio_desc *dc_gpio;
> > +     u32 max_spi_speed;
> > +     struct regulator *vcc;
> > +};
> > +
> > +/*
> > + * The Stm32f429-disco board has a panel ili9341 connected to ltdc controller
> > + */
> > +static const struct ili9341_config ili9341_stm32f429_disco_data = {
> > +     .max_spi_speed = 10000000,
> > +     .mode = {
> > +             .clock = 6100,
> > +             .hdisplay = 240,
> > +             .hsync_start = 240 + 10,/* hfp 10 */
> > +             .hsync_end = 240 + 10 + 10,/* hsync 10 */
> > +             .htotal = 240 + 10 + 10 + 20,/* hbp 20 */
> > +             .vdisplay = 320,
> > +             .vsync_start = 320 + 4,/* vfp 4 */
> > +             .vsync_end = 320 + 4 + 2,/* vsync 2 */
> > +             .vtotal = 320 + 4 + 2 + 2,/* vbp 2 */
> > +             .flags = 0,
> > +             .width_mm = 65,
> > +             .height_mm = 50,
> > +             .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> > +     },
> > +     /* TODO: need comments for this register */
> > +     .ca = {0xc3, 0x08, 0x50},
> > +     /* TODO: need comments for this register */
> > +     .power_b = {0x00, 0xc1, 0x30},
> > +     /* TODO: need comments for this register */
> > +     .power_seq = {0x64, 0x03, 0x12, 0x81},
> > +     /* TODO: need comments for this register */
> > +     .dtca = {0x85, 0x00, 0x78},
> > +     /* TODO: need comments for this register */
> > +     .power_a = {0x39, 0x2c, 0x00, 0x34, 0x02},
> > +     /* TODO: need comments for this register */
> > +     .prc = 0x20,
> > +     /* TODO: need comments for this register */
> > +     .dtcb = {0x00, 0x00},
> > +     /* 0x00 fosc, 0x1b 70hz */
> > +     .frc = {0x00, 0x1b},
> > +     /* 0x0a Interval scan, AGND AGND AGND AGND
> > +      * 0xa2 Normally white, G1 -> G320, S720 -> S1,
> > +      *      Scan Cycle 5 frames,85ms
> > +      */
> > +     .dfc_1 = {0x0a, 0xa2},
> > +     /* 0x10 3.65v */
> > +     .power_1 = 0x10,
> > +     /* 0x10 AVDD=vci*2, VGH=vci*7, VGL=-vci*4 */
> > +     .power_2 = 0x10,
> > +     /* 0x45 VCOMH 4.425v, 0x15 VCOML -1.975*/
> > +     .vcom_1 = {0x45, 0x15},
> > +     /* 0x90 offset voltage, VMH-48, VML-48 */
> > +     .vcom_2 = 0x90,
> > +     /* 0xc8 Row Address Order, Column Address Order
> > +      *      BGR 1
> > +      */
> > +     .address_mode = 0xc8,
> > +     .g3amma_en = 0x00,
> > +     /* 0xc2
> > +      * Display Data Path: Memory
> > +      * RGB: DE mode
> > +      * DOTCLK polarity set (data fetched at the falling time)
> > +      */
> > +     .rgb_interface = ILI9341_RGB_DISP_PATH_MEM |
> > +                     ILI9341_RGB_DE_MODE |
> > +                     ILI9341_RGB_DPL,
> > +     /*
> > +      * 0x0a
> > +      * Gate outputs in non-display area: Interval scan
> > +      * Determine source/VCOM output in a non-display area in the partial
> > +      * display mode: AGND AGND AGND AGND
> > +      *
> > +      * 0xa7
> > +      * Scan Cycle: 15 frames
> > +      * fFLM = 60Hz: 255ms
> > +      * Liquid crystal type: Normally white
> > +      * Gate Output Scan Direction: G1 -> G320
> > +      * Source Output Scan Direction: S720 -> S1
> > +      *
> > +      * 0x27
> > +      * LCD Driver Line: 320 lines
> > +      *
> > +      * 0x04
> > +      * PCDIV: 4
> > +      */
> > +     .dfc_2 = {0x0a, 0xa7, 0x27, 0x04},
> > +     /* column address: 240 */
> > +     .column_addr = {0x00, 0x00, (ILI9341_COLUMN_ADDR >> 4) & 0xff,
> > +                             ILI9341_COLUMN_ADDR & 0xff},
> > +     /* page address: 320 */
> > +     .page_addr = {0x00, 0x00, (ILI9341_PAGE_ADDR >> 4) & 0xff,
> > +                             ILI9341_PAGE_ADDR & 0xff},
> > +     /* Memory write control: When the transfer number of data exceeds
> > +      * (EC-SC+1)*(EP-SP+1), the column and page number will be
> > +      * reset, and the exceeding data will be written into the following
> > +      * column and page.
> > +      * Display Operation Mode: RGB Interface Mode
> > +      * Interface for RAM Access: RGB interface
> > +      * 16- bit RGB interface (1 transfer/pixel)
> > +      */
> > +     .interface = {ILI9341_IF_WE_MODE, 0x00,
> > +                     ILI9341_IF_DM_RGB | ILI9341_IF_RM_RGB},
> > +     /* DPI: 16 bits / pixel */
> > +     .pixel_format = ILI9341_PIXEL_DPI_16_BITS,
> > +     /* Curve Selected: Gamma curve 1 (G2.2) */
> > +     .gamma_curve = ILI9341_GAMMA_CURVE_1,
> > +     .pgamma = {0x0f, 0x29, 0x24, 0x0c, 0x0e,
> > +                     0x09, 0x4e, 0x78, 0x3c, 0x09,
> > +                     0x13, 0x05, 0x17, 0x11, 0x00},
> > +     .ngamma = {0x00, 0x16, 0x1b, 0x04, 0x11,
> > +                     0x07, 0x31, 0x33, 0x42, 0x05,
> > +                     0x0c, 0x0a, 0x28, 0x2f, 0x0f},
> > +};
> > +
> > +static inline struct ili9341 *panel_to_ili9341(struct drm_panel *panel)
> > +{
> > +     return container_of(panel, struct ili9341, panel);
> > +}
> > +
> > +static int ili9341_spi_transfer(struct spi_device *spi, u32 speed_hz,
> > +                       u8 bpw, const void *buf, size_t len)
> > +{
> > +     size_t max_chunk = spi_max_transfer_size(spi);
> > +     struct spi_transfer tr = {
> > +             .bits_per_word = bpw,
> > +             .speed_hz = speed_hz,
> > +             .len = len,
> > +     };
> > +     struct spi_message m;
> > +     size_t chunk;
> > +     int ret;
> > +
> > +     spi_message_init_with_transfers(&m, &tr, 1);
> > +
> > +     while (len) {
> > +             chunk = min(len, max_chunk);
> > +
> > +             tr.tx_buf = buf;
> > +             tr.len = chunk;
> > +             buf += chunk;
> > +             len -= chunk;
> > +
> > +             ret = spi_sync(spi, &m);
> > +             if (ret) {
> > +                     dev_err(&spi->dev, "spi_sync error: %d\n", ret);
> > +                     return ret;
> > +             }
> > +     }
> > +     return 0;
> > +}
> > +
> > +static int _ili9341_command(struct ili9341 *ili, u8 cmd, const void *data,
> > +                                 size_t count)
> > +{
> > +     struct spi_device *spi = to_spi_device(ili->dev);
> > +     int ret = 0;
> > +
> > +     gpiod_set_value_cansleep(ili->dc_gpio, 0);
> > +
> > +     ret = ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
> > +                                     (const void *)&cmd, 1);
> > +     if (ret || data == NULL || count == 0) {
> > +             return ret;
> > +     }
> > +
> > +     gpiod_set_value_cansleep(ili->dc_gpio, 1);
> > +
> > +     return ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
> > +             data, count);
> > +}
> > +
> > +static int ili9341_dpi_init(struct ili9341 *ili)
> > +{
> > +     int ret;
> > +     ret = _ili9341_command(ili, 0xca,
> > +                     ili->conf->ca,
> > +                     ILI9341_CA_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_POWERB,
> > +                     ili->conf->power_b,
> > +                     ILI9341_POWER_B_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_POWER_SEQ,
> > +                     ili->conf->power_seq,
> > +                     ILI9341_POWER_SEQ_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_DTCA,
> > +                     ili->conf->dtca,
> > +                     ILI9341_DTCA_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_POWERA,
> > +                     ili->conf->power_a,
> > +                     ILI9341_POWER_A_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_PRC,
> > +                     &ili->conf->prc,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_DTCB,
> > +                     ili->conf->dtcb,
> > +                     ILI9341_DTCB_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_FRC,
> > +                     ili->conf->frc,
> > +                     ILI9341_FRC_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_DFC,
> > +                     ili->conf->dfc_1,
> > +                     ILI9341_DFC_1_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_POWER1,
> > +                     &ili->conf->power_1,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_POWER2,
> > +                     &ili->conf->power_2,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_VCOM1,
> > +                     ili->conf->vcom_1,
> > +                     ILI9341_VCOM_1_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_VCOM2,
> > +                     &ili->conf->vcom_2,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, MIPI_DCS_SET_ADDRESS_MODE,
> > +                     &ili->conf->address_mode,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_3GAMMA_EN,
> > +                     &ili->conf->g3amma_en,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_RGB_INTERFACE,
> > +                     &ili->conf->rgb_interface,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_DFC,
> > +                     ili->conf->dfc_2,
> > +                     ILI9341_DFC_2_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, MIPI_DCS_SET_COLUMN_ADDRESS,
> > +                     ili->conf->column_addr,
> > +                     ILI9341_COLUMN_ADDR_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, MIPI_DCS_SET_PAGE_ADDRESS,
> > +                     ili->conf->page_addr,
> > +                     ILI9341_PAGE_ADDR_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_INTERFACE,
> > +                     ili->conf->interface,
> > +                     ILI9341_INTERFACE_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, MIPI_DCS_SET_PIXEL_FORMAT,
> > +                     &ili->conf->pixel_format,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
> > +     if (ret)
> > +             return ret;
> > +
> > +     msleep(200);
> > +     ret = _ili9341_command(ili, MIPI_DCS_SET_GAMMA_CURVE,
> > +                     &ili->conf->gamma_curve,
> > +                     1);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_PGAMMA,
> > +                     ili->conf->pgamma,
> > +                     ILI9341_PGAMMA_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = _ili9341_command(ili, ILI9341_NGAMMA,
> > +                     ili->conf->ngamma,
> > +                     ILI9341_NGAMMA_LEN);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = ili9341_command(ili, MIPI_DCS_EXIT_SLEEP_MODE);
> > +     if (ret)
> > +             return ret;
> > +
> > +     msleep(200);
> > +     ret = ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
> > +     if (ret)
> > +             return ret;
> > +
> > +     dev_info(ili->dev, "initialized display rgb interface\n");
> > +
> > +     return 0;
> > +}
> > +
> > +static int ili9341_dpi_power_on(struct ili9341 *ili)
> > +{
> > +     int ret = 0;
> > +
> > +     /* Assert RESET */
> > +     gpiod_set_value(ili->reset_gpio, 1);
> > +
> > +     /* Enable power */
> > +     if (!IS_ERR(ili->vcc)) {
> > +             ret = regulator_enable(ili->vcc);
> > +             if (ret < 0) {
> > +                     dev_err(ili->dev, "unable to enable vcc\n");
> > +                     return ret;
> > +             }
> > +     }
> > +     msleep(20);
> > +
> > +     /* De-assert RESET */
> > +     gpiod_set_value(ili->reset_gpio, 0);
> > +     msleep(10);
> > +
> > +     return 0;
> > +}
> > +
> > +static int ili9341_dpi_power_off(struct ili9341 *ili)
> > +{
> > +     /* Assert RESET */
> > +     gpiod_set_value(ili->reset_gpio, 1);
> > +
> > +     /* Disable power */
> > +     if (!IS_ERR(ili->vcc))
> > +             return regulator_disable(ili->vcc);
> > +
> > +     return 0;
> > +}
> > +
> > +static int ili9341_dpi_disable(struct drm_panel *panel)
> > +{
> > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > +
> > +     ili9341_command(ili, MIPI_DCS_SET_DISPLAY_OFF);
> > +
> > +     return 0;
> > +}
> > +
> > +static int ili9341_dpi_unprepare(struct drm_panel *panel)
> > +{
> > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > +
> > +     return ili9341_dpi_power_off(ili);
> > +}
> > +
> > +static int ili9341_dpi_prepare(struct drm_panel *panel)
> > +{
> > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > +     int ret;
> > +
> > +     ret = ili9341_dpi_power_on(ili);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = ili9341_dpi_init(ili);
> > +     if (ret < 0)
> > +             ili9341_dpi_unprepare(panel);
> > +
> > +     return ret;
> > +}
> > +
> > +static int ili9341_dpi_enable(struct drm_panel *panel)
> > +{
> > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > +
> > +     ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
> > +
> > +     return 0;
> > +}
> > +
> > +static int ili9341_dpi_get_modes(struct drm_panel *panel,
> > +                             struct drm_connector *connector)
> > +{
> > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > +     struct drm_device *drm = connector->dev;
> > +     struct drm_display_mode *mode;
> > +     struct drm_display_info *info;
> > +
> > +     info = &connector->display_info;
> > +     info->width_mm = ili->conf->mode.width_mm;
> > +     info->height_mm = ili->conf->mode.height_mm;
> > +
> > +     if (ili->conf->rgb_interface & ILI9341_RGB_DPL)
> > +             info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
> > +     else
> > +             info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
> > +
> > +     if (ili->conf->rgb_interface & ILI9341_RGB_EPL)
> > +             info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
> > +     else
> > +             info->bus_flags |= DRM_BUS_FLAG_DE_HIGH;
> > +
> > +     mode = drm_mode_duplicate(drm, &ili->conf->mode);
> > +     if (!mode) {
> > +             DRM_ERROR("bad mode or failed to add mode\n");
> > +             return -EINVAL;
> > +     }
> > +     drm_mode_set_name(mode);
> > +
> > +     /* Set up the polarity */
> > +     if (ili->conf->rgb_interface & ILI9341_RGB_HSPL)
> > +             mode->flags |= DRM_MODE_FLAG_PHSYNC;
> > +     else
> > +             mode->flags |= DRM_MODE_FLAG_NHSYNC;
> > +
> > +     if (ili->conf->rgb_interface & ILI9341_RGB_VSPL)
> > +             mode->flags |= DRM_MODE_FLAG_PVSYNC;
> > +     else
> > +             mode->flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +     drm_mode_probed_add(connector, mode);
> > +
> > +     return 1; /* Number of modes */
> > +}
> > +
> > +static const struct drm_panel_funcs ili9341_dpi_funcs = {
> > +     .disable = ili9341_dpi_disable,
> > +     .unprepare = ili9341_dpi_unprepare,
> > +     .prepare = ili9341_dpi_prepare,
> > +     .enable = ili9341_dpi_enable,
> > +     .get_modes = ili9341_dpi_get_modes,
> > +};
> > +
> > +static int ili9341_dpi_probe(struct spi_device *spi)
> > +{
> > +     int ret;
> > +     struct device *dev = &spi->dev;
> > +     struct ili9341 *ili;
> > +
> > +     ili = devm_kzalloc(dev, sizeof(struct ili9341), GFP_KERNEL);
> > +     if (!ili)
> > +             return -ENOMEM;
> > +
> > +     spi_set_drvdata(spi, ili);
> > +
> > +     ili->dev = dev;
> > +     /*
> > +      * Every new incarnation of this display must have a unique
> > +      * data entry for the system in this driver.
> > +      */
> > +     ili->conf = of_device_get_match_data(dev);
> > +     if (!ili->conf) {
> > +             dev_err(dev, "missing device configuration\n");
> > +             return -ENODEV;
> > +     }
> > +
> > +     ili->vcc = devm_regulator_get_optional(dev, "vcc");
> > +     if (IS_ERR(ili->vcc))
> > +             dev_err(dev, "get optional vcc failed\n");
> > +
> > +     ili->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> > +             GPIOD_OUT_HIGH);
> > +     if (IS_ERR(ili->reset_gpio)) {
> > +             dev_err(dev, "failed to get RESET GPIO\n");
> > +             return PTR_ERR(ili->reset_gpio);
> > +     }
> > +
> > +     ili->dc_gpio = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
> > +     if (IS_ERR(ili->dc_gpio)) {
> > +             dev_err(dev, "failed to get DC GPIO\n");
> > +             return PTR_ERR(ili->dc_gpio);
> > +     }
> > +
> > +     spi->bits_per_word = 8;
> > +     ret = spi_setup(spi);
> > +     if (ret < 0) {
> > +             dev_err(dev, "spi setup failed.\n");
> > +             return ret;
> > +     }
> > +
> > +     ili->max_spi_speed = ili->conf->max_spi_speed;
> > +
> > +     drm_panel_init(&ili->panel, dev, &ili9341_dpi_funcs,
> > +                    DRM_MODE_CONNECTOR_DPI);
> > +
> > +     drm_panel_add(&ili->panel);
> > +
> > +     return 0;
> > +}
> > +
> > +
> > +
> > +static void ili9341_dbi_enable(struct drm_simple_display_pipe *pipe,
> > +                          struct drm_crtc_state *crtc_state,
> > +                          struct drm_plane_state *plane_state)
> > +{
> > +     struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
> > +     struct mipi_dbi *dbi = &dbidev->dbi;
> > +     u8 addr_mode;
> > +     int ret, idx;
> > +
> > +     if (!drm_dev_enter(pipe->crtc.dev, &idx))
> > +             return;
> > +
> > +     DRM_DEBUG_KMS("\n");
> > +
> > +     ret = mipi_dbi_poweron_conditional_reset(dbidev);
> > +     if (ret < 0)
> > +             goto out_exit;
> > +     if (ret == 1)
> > +             goto out_enable;
> > +
> > +     mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
> > +
> > +     mipi_dbi_command(dbi, ILI9341_POWERB, 0x00, 0xc1, 0x30);
> > +     mipi_dbi_command(dbi, ILI9341_POWER_SEQ, 0x64, 0x03, 0x12, 0x81);
> > +     mipi_dbi_command(dbi, ILI9341_DTCA, 0x85, 0x00, 0x78);
> > +     mipi_dbi_command(dbi, ILI9341_POWERA, 0x39, 0x2c, 0x00, 0x34, 0x02);
> > +     mipi_dbi_command(dbi, ILI9341_PRC, ILI9341_DBI_PRC_NORMAL);
> > +     mipi_dbi_command(dbi, ILI9341_DTCB, 0x00, 0x00);
> > +
> > +     /* Power Control */
> > +     mipi_dbi_command(dbi, ILI9341_POWER1, ILI9341_DBI_VCOMH_4P6V);
> > +     mipi_dbi_command(dbi, ILI9341_POWER2, ILI9341_DBI_PWR_2_DEFAULT);
> > +     /* VCOM */
> > +     mipi_dbi_command(dbi, ILI9341_VCOM1, ILI9341_DBI_VCOM_1_VMH_4P25V,
> > +                                             ILI9341_DBI_VCOM_1_VML_1P5V);
> > +     mipi_dbi_command(dbi, ILI9341_VCOM2, ILI9341_DBI_VCOM_2_DEC_58);
> > +
> > +     /* Memory Access Control */
> > +     mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT,
> > +                             MIPI_DCS_PIXEL_FMT_16BIT);
> > +
> > +     /* Frame Rate */
> > +     mipi_dbi_command(dbi, ILI9341_FRC, ILI9341_DBI_FRC_DIVA & 0x03,
> > +                                             ILI9341_DBI_FRC_RTNA & 0x1f);
> > +
> > +     /* Gamma */
> > +     mipi_dbi_command(dbi, ILI9341_3GAMMA_EN, 0x00);
> > +     mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, ILI9341_GAMMA_CURVE_1);
> > +     mipi_dbi_command(dbi, ILI9341_PGAMMA,
> > +                      0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
> > +                      0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
> > +     mipi_dbi_command(dbi, ILI9341_NGAMMA,
> > +                      0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
> > +                      0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
> > +
> > +     /* DDRAM */
> > +     mipi_dbi_command(dbi, ILI9341_ETMOD, ILI9341_DBI_EMS_GAS |
> > +                                             ILI9341_DBI_EMS_DTS |
> > +                                             ILI9341_DBI_EMS_GON);
> > +
> > +     /* Display */
> > +     mipi_dbi_command(dbi, ILI9341_DFC, 0x08, 0x82, 0x27, 0x00);
> > +     mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
> > +     msleep(100);
> > +
> > +     mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
> > +     msleep(100);
> > +
> > +out_enable:
> > +     switch (dbidev->rotation) {
> > +     default:
> > +             addr_mode = ILI9341_MADCTL_MX;
> > +             break;
> > +     case 90:
> > +             addr_mode = ILI9341_MADCTL_MV;
> > +             break;
> > +     case 180:
> > +             addr_mode = ILI9341_MADCTL_MY;
> > +             break;
> > +     case 270:
> > +             addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
> > +                         ILI9341_MADCTL_MX;
> > +             break;
> > +     }
> > +     addr_mode |= ILI9341_MADCTL_BGR;
> > +     mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
> > +     mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
> > +     DRM_DEBUG_KMS("initialized display serial interface\n");
> > +out_exit:
> > +     drm_dev_exit(idx);
> > +}
> > +
> > +static const struct drm_simple_display_pipe_funcs ili9341_dbi_funcs = {
> > +     .enable = ili9341_dbi_enable,
> > +     .disable = mipi_dbi_pipe_disable,
> > +     .update = mipi_dbi_pipe_update,
> > +     .prepare_fb = drm_gem_simple_display_pipe_prepare_fb,
> > +};
> > +
> > +static const struct drm_display_mode ili9341_dbi_mode = {
> > +     DRM_SIMPLE_MODE(240, 320, 37, 49),
> > +};
> > +
> > +DEFINE_DRM_GEM_CMA_FOPS(ili9341_dbi_fops);
> > +
> > +static struct drm_driver ili9341_dbi_driver = {
> > +     .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> > +     .fops                   = &ili9341_dbi_fops,
> > +     DRM_GEM_CMA_DRIVER_OPS_VMAP,
> > +     .debugfs_init           = mipi_dbi_debugfs_init,
> > +     .name                   = "ili9341",
> > +     .desc                   = "Ilitek ILI9341",
> > +     .date                   = "20180514",
> > +     .major                  = 1,
> > +     .minor                  = 0,
> > +};
> > +static int ili9341_dbi_probe(struct spi_device *spi)
> > +{
> > +     struct mipi_dbi_dev *dbidev;
> > +     struct drm_device *drm;
> > +     struct mipi_dbi *dbi;
> > +     struct gpio_desc *dc;
> > +     struct device *dev = &spi->dev;
> > +     u32 rotation = 0;
> > +     int ret;
> > +
> > +     dbidev = devm_drm_dev_alloc(dev, &ili9341_dbi_driver,
> > +                                 struct mipi_dbi_dev, drm);
> > +     if (IS_ERR(dbidev))
> > +             return PTR_ERR(dbidev);
> > +
> > +     dbi = &dbidev->dbi;
> > +     drm = &dbidev->drm;
> > +
> > +     drm_mode_config_init(drm);
> > +
> > +     dbi->reset = devm_gpiod_get_optional(dev, "reset",
> > +                                     GPIOD_OUT_HIGH);
> > +     if (IS_ERR(dbi->reset)) {
> > +             DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
> > +             return PTR_ERR(dbi->reset);
> > +     }
> > +
> > +     dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
> > +     if (IS_ERR(dc)) {
> > +             DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
> > +             return PTR_ERR(dc);
> > +     }
> > +
> > +     dbidev->regulator = devm_regulator_get_optional(dev, "vcc");
> > +     if (IS_ERR(dbidev->regulator))
> > +             dev_err(dev, "get optional vcc failed\n");
> > +
> > +     dbidev->backlight = devm_of_find_backlight(dev);
> > +     if (IS_ERR(dbidev->backlight))
> > +             return PTR_ERR(dbidev->backlight);
> > +
> > +     device_property_read_u32(dev, "rotation", &rotation);
> > +
> > +     ret = mipi_dbi_spi_init(spi, dbi, dc);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = mipi_dbi_dev_init(dbidev, &ili9341_dbi_funcs,
> > +                                     &ili9341_dbi_mode, rotation);
> > +     if (ret)
> > +             return ret;
> > +
> > +     drm_mode_config_reset(drm);
> > +
> > +     ret = drm_dev_register(drm, 0);
> > +     if (ret)
> > +             return ret;
> > +
> > +     spi_set_drvdata(spi, drm);
> > +
> > +     drm_fbdev_generic_setup(drm, 0);
> > +
> > +     return 0;
> > +}
> > +static int ili9341_probe(struct spi_device *spi)
> > +{
> > +     const struct spi_device_id *id = spi_get_device_id(spi);
> > +
> > +     if (!strcmp(id->name, "sf-tc240t-9370-t"))
> > +             return ili9341_dpi_probe(spi);
> > +     else if (!strcmp(id->name, "yx240qv29"))
> > +             return ili9341_dbi_probe(spi);
> > +
> > +     return -1;
> > +}
> > +
> > +static int ili9341_remove(struct spi_device *spi)
> > +{
> > +     const struct spi_device_id *id = spi_get_device_id(spi);
> > +     struct ili9341 *ili = spi_get_drvdata(spi);
> > +     struct drm_device *drm = spi_get_drvdata(spi);
> > +
> > +     if (!strcmp(id->name, "sf-tc240t-9370-t")) {
> > +             ili9341_dpi_power_off(ili);
> > +             drm_panel_remove(&ili->panel);
> > +     } else if (!strcmp(id->name, "yx240qv29")) {
> > +             drm_dev_unplug(drm);
> > +             drm_atomic_helper_shutdown(drm);
> > +     }
> > +     return 0;
> > +}
> > +
> > +static void ili9341_shutdown(struct spi_device *spi)
> > +{
> > +     const struct spi_device_id *id = spi_get_device_id(spi);
> > +
> > +     if (!strcmp(id->name, "yx240qv29"))
> > +             drm_atomic_helper_shutdown(spi_get_drvdata(spi));
> > +}
> > +
> > +static const struct of_device_id ili9341_of_match[] = {
> > +     {
> > +             .compatible = "st,sf-tc240t-9370-t",
> > +             .data = &ili9341_stm32f429_disco_data,
> > +     },
> > +     {
> > +             /* porting from tiny/ili9341.c
> > +              * for original mipi dbi compitable
> > +              */
> > +             .compatible = "adafruit,yx240qv29",
> > +             .data = NULL,
> > +     },
> > +};
> > +MODULE_DEVICE_TABLE(of, ili9341_of_match);
> > +
> > +static const struct spi_device_id ili9341_id[] = {
> > +     { "yx240qv29", 0 },
> > +     { "sf-tc240t-9370-t", 0 },
> > +     { }
> > +};
> > +MODULE_DEVICE_TABLE(spi, ili9341_id);
> > +
> > +static struct spi_driver ili9341_driver = {
> > +     .probe = ili9341_probe,
> > +     .remove = ili9341_remove,
> > +     .shutdown = ili9341_shutdown,
> > +     .id_table = ili9341_id,
> > +     .driver = {
> > +             .name = "panel-ilitek-ili9341",
> > +             .of_match_table = ili9341_of_match,
> > +     },
> > +};
> > +module_spi_driver(ili9341_driver);
> > +
> > +MODULE_AUTHOR("Dillon Min <dillon.minfei@gmail.com>");
> > +MODULE_DESCRIPTION("ILI9341 LCD panel driver");
> > +MODULE_LICENSE("GPL v2");
> >

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-31 13:38   ` Dillon Min
@ 2021-05-31 13:50     ` Patrice CHOTARD
  2021-05-31 14:29       ` Dillon Min
  0 siblings, 1 reply; 20+ messages in thread
From: Patrice CHOTARD @ 2021-05-31 13:50 UTC (permalink / raw)
  To: Dillon Min
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media



On 5/31/21 3:38 PM, Dillon Min wrote:
> Hi Patrice
> 
> Thanks for your time to test my patch.
> 
> On Mon, May 31, 2021 at 9:20 PM Patrice CHOTARD
> <patrice.chotard@foss.st.com> wrote:
>>
>> Hi Dillon
>>
>>
>>
>> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
>>> From: Dillon Min <dillon.minfei@gmail.com>
>>>
>>> This seriese fix three i2c/clk bug for stm32 f4/f7
>>> - kernel runing in sdram, i2c driver get data timeout
>>> - ltdc clk turn off after kernel console active
>>> - kernel hang in set ltdc clock rate
>>>
>>> clk bug found on stm32f429/f469-disco board
>>>
>>> Hi Patrice:
>>> below is the guide to verify the patch:
>>>
>>> setup test env with following files(link at below 'files link'):
>>> [1] u-boot-dtb.bin
>>> [2] rootfs zip file (used in kernel initramfs)
>>> [3] u-boot's mkimage to create itb file
>>> [4] kernel config file
>>> [5] my itb with-or-without i2c patch
>>>
>>> This patch based on kernel commit:
>>> 88b06399c9c766c283e070b022b5ceafa4f63f19
>>>
>>> Note:
>>> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
>>> get accepted. it's used to setup touch screen calibration, then test i2c.
>>>
>>> create itb file(please correct path of 'data'):
>>> ./mkimage -f stm32.its stm32.itb
>>>
>>> HW setup:
>>> console:
>>>        PA9, PA10
>>>        usart0
>>>        serial@40011000
>>>        115200 8n1
>>>
>>> -- flash u-boot.bin to stm32f429-disco on PC
>>> $ sudo openocd -f board/stm32f429discovery.cfg -c \
>>>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
>>>
>>> -- setup kernel load bootargs at u-boot
>>> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
>>>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
>>> U-Boot > loady;bootm
>>> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
>>>
>>
>>
>> Thanks for these informations
>> I was able to load and boot DTB and uImage directly in SDRAM as you suggested,
>> i saw Linux logo and kernel log on the STM32F429-disco display,
>> but i can't reach the login.
>>
>> The last kernel log i got is :
>>
>> Starting kernel ...
>>
>> [    0.000000] Booting Linux on physical CPU 0x0
>> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
>> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
>> [    0.000000] CPU: unknown data cache, unknown instruction cache
>> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
>> [    0.000000] Zone ranges:
>> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
>> [    0.000000] Movable zone start for each node
>> [    0.000000] Early memory node ranges
>>
>> [...]
>>
>> [    2.637564] printk: console [ttySTM0] enabled
>> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
>> [    2.758986] spi_stm32 40015000.spi: driver initialized
>> [    2.795733] i2c /dev entries driver
>> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
>> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
>> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
>> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
>> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
>> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
>> [    3.765208] Console: switching to colour frame buffer device 30x40
>> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
>> [    4.212737] Freeing unused kernel memory: 324K
>> [    4.287300] This architecture does not have kernel memory protection.
>> [    4.401202] Run /linuxrc as init process
>> [    4.478622]   with arguments:
>> [    4.555069]     /linuxrc
>> [    4.595406]   with environment:
>> [    4.672213]     HOME=/
>> [    4.712511]     TERM=linux
>> [  206.785289] random: crng init done
> 
> I guess you didn't add the rootfs to uImage I sent you.

I do use your rootfs

> Could you post all the logs from u-boot startup to kernel log end.


U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)                                   
                                                                                    
DRAM:  8 MiB                                                                        
Flash: 2 MiB                                                                        
Loading Environment from Flash... OK                                                
In:    serial@40011000                                                              
Out:   serial@40011000                                                              
Err:   serial@40011000                                                              
Hit any key to stop autoboot:  0                                                    
U-Boot >    setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/lin'
U-Boot >                                                                            
U-Boot >                                                                            
U-Boot > setenv loadaddr 0x90400000                                                 
U-Boot > loady                                                                      
## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...                
CxyzModem - CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 7 retries                     
## Total Size      = 0x00004cad = 19629 Bytes                                       
U-Boot > setenv loadaddr 0x90406000                                                 
U-Boot > loady
## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...                
C- CRC mode, 12453(SOH)/0(STX)/0(CAN) packets, 4 retries
## Total Size      = 0x00185140 = 1593664 Bytes
U-Boot > bootm 0x90406000 - 0x90400000
## Booting kernel from Legacy Image at 90406000 ...
   Image Name:   Linux-5.13.0-rc1-00082-g9dbbd5cb
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1593600 Bytes = 1.5 MiB
   Load Address: 90008000
   Entry Point:  90008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 90400000
   Booting using the fdt blob at 0x90400000
   Loading Kernel Image
   Loading Device Tree to 905b9000, end 905c0cac ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
[    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: unknown data cache, unknown instruction cache
[    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] On node 0 totalpages: 2048
[    0.000000]   Normal zone: 16 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 2048 pages, LIFO batch:0
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
[    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdin2
[    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 5264K/8192K available (1372K kernel code, 302K rwdata, 516K rodata,)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000]  Trampoline variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] /soc/interrupt-controller@40013c00: bank0
[    0.000000] random: get_random_bytes called from start_kernel+0x203/0x370 with crng_ini0
[    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idls
[    0.000000] ARM System timer initialized as clocksource
[    0.000026] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
[    0.000665] timer@40000c00: STM32 sched_clock registered
[    0.001275] Switching to timer-based delay loop, resolution 11ns
[    0.001712] timer@40000c00: STM32 delay timer registered
[    0.002253] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_is
[    0.003076] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
[    0.014135] Console: colour dummy device 80x30
[    0.062375] printk: console [tty0] enabled
[    0.063843] Calibrating delay loop (skipped), value calculated using timer frequency.. )
[    0.066453] pid_max: default: 4096 minimum: 301
[    0.071393] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.073734] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.104759] rcu: Hierarchical SRCU implementation.
[    0.111552] devtmpfs: initialized
[    0.339332] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:s
[    0.341835] pinctrl core: initialized pinctrl subsystem
[    0.658423] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
[    0.680505] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
[    0.689824] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
[    0.699409] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
[    0.708775] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
[    0.718094] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
[    0.727535] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
[    0.736953] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
[    0.746404] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
[    0.756098] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
[    0.765436] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
[    0.774870] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
[    0.776730] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
[    0.997446] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
[    1.029604] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
[    1.043098] clocksource: Switched to clocksource timer@40000c00
[    1.358086] workingset: timestamp_bits=30 max_order=11 bucket_order=0
[    1.632751] io scheduler mq-deadline registered           
[    1.634287] io scheduler kyber registered
[    1.650574] STM32 USART driver initialized
[    1.661272] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000)t
[    2.603317] random: fast init done
[    2.637564] printk: console [ttySTM0] enabled
[    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
[    2.758986] spi_stm32 40015000.spi: driver initialized
[    2.795733] i2c /dev entries driver
[    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
[    2.922030] stmpe-ts stmpe-ts: DMA mask not set
[    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
[    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
[    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
[    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
[    3.765208] Console: switching to colour frame buffer device 30x40
[    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
[    4.212737] Freeing unused kernel memory: 324K
[    4.287300] This architecture does not have kernel memory protection.
[    4.401202] Run /linuxrc as init process
[    4.478622]   with arguments:
[    4.555069]     /linuxrc
[    4.595406]   with environment:
[    4.672213]     HOME=/
[    4.712511]     TERM=linux
[  206.785289] random: crng init done


> 
> If possible, you can try my suggestion.
> - tar -jxf stm32_rootfs.tar.bz2
> - add stm32_rootfs to your kernel config( enable initramfs)

As explained above, that's what i did

> - make O=YOUR_KERNEL_OUT zImage dtbs LOADADDR=0x90008000



> - create itb file (combine dtb and kernel, initramfs) by mkimage
>   ./mkimage -f stm32.its stm32.itb

I didn't use .itb file, but directly uImage loaded @0x90406000 and stm32f429-disco.dtb loaded @0x90400000

How do you generate .its file ?


>   (before above command, make sure you correct stm32.its adapt to your env)
> 
> This process will make u-boot to load the kernel more simple.
> 
> Thanks.
> 
> Best Regards.
> Dillon
> 
> 
>>
>>
>> I can't test your I2C patch.
>>
>> Patrice
>>
>>
>>> -- setup ts_calibrate running env on stm32f429-disco
>>> / # export TSLIB_CONFFILE=/etc/ts.conf
>>> / # export TSLIB_TSDEVICE=/dev/input/event0
>>> / # export TSLIB_CONSOLEDEVICE=none
>>> / # export TSLIB_FBDEVICE=/dev/fb0
>>>
>>> -- clear screen
>>> / # ./fb
>>>
>>> -- run ts_calibrate
>>> / # ts_calibrate
>>> (you can calibrate touchscreen now, and get below errors)
>>>
>>> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
>>> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
>>> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
>>> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
>>>
>>> ...
>>> with i2c patch applied, you will find below logs:
>>>
>>> RAW---------------------> 3164 908 183 118.110884
>>> TS_READ_RAW----> x = 3164, y =908, pressure = 183
>>> RAW---------------------> 3166 922 126 118.138946
>>> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
>>> ....
>>>
>>> files link:
>>> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
>>>
>>>
>>>
>>>
>>> Dillon Min (4):
>>>   drm/panel: Add ilitek ili9341 panel driver
>>>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
>>>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
>>>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
>>>     kernel startup
>>>
>>>  drivers/clk/clk-stm32f4.c                    |   10 +-
>>>  drivers/gpu/drm/panel/Kconfig                |   12 +
>>>  drivers/gpu/drm/panel/Makefile               |    1 +
>>>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
>>>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
>>>  5 files changed, 1310 insertions(+), 10 deletions(-)
>>>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
>>>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-31 13:50     ` Patrice CHOTARD
@ 2021-05-31 14:29       ` Dillon Min
  2021-05-31 14:58         ` Patrice CHOTARD
  0 siblings, 1 reply; 20+ messages in thread
From: Dillon Min @ 2021-05-31 14:29 UTC (permalink / raw)
  To: Patrice CHOTARD
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

Hi Patrice

On Mon, May 31, 2021 at 9:51 PM Patrice CHOTARD
<patrice.chotard@foss.st.com> wrote:
>
>
>
> On 5/31/21 3:38 PM, Dillon Min wrote:
> > Hi Patrice
> >
> > Thanks for your time to test my patch.
> >
> > On Mon, May 31, 2021 at 9:20 PM Patrice CHOTARD
> > <patrice.chotard@foss.st.com> wrote:
> >>
> >> Hi Dillon
> >>
> >>
> >>
> >> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> >>> From: Dillon Min <dillon.minfei@gmail.com>
> >>>
> >>> This seriese fix three i2c/clk bug for stm32 f4/f7
> >>> - kernel runing in sdram, i2c driver get data timeout
> >>> - ltdc clk turn off after kernel console active
> >>> - kernel hang in set ltdc clock rate
> >>>
> >>> clk bug found on stm32f429/f469-disco board
> >>>
> >>> Hi Patrice:
> >>> below is the guide to verify the patch:
> >>>
> >>> setup test env with following files(link at below 'files link'):
> >>> [1] u-boot-dtb.bin
> >>> [2] rootfs zip file (used in kernel initramfs)
> >>> [3] u-boot's mkimage to create itb file
> >>> [4] kernel config file
> >>> [5] my itb with-or-without i2c patch
> >>>
> >>> This patch based on kernel commit:
> >>> 88b06399c9c766c283e070b022b5ceafa4f63f19
> >>>
> >>> Note:
> >>> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
> >>> get accepted. it's used to setup touch screen calibration, then test i2c.
> >>>
> >>> create itb file(please correct path of 'data'):
> >>> ./mkimage -f stm32.its stm32.itb
> >>>
> >>> HW setup:
> >>> console:
> >>>        PA9, PA10
> >>>        usart0
> >>>        serial@40011000
> >>>        115200 8n1
> >>>
> >>> -- flash u-boot.bin to stm32f429-disco on PC
> >>> $ sudo openocd -f board/stm32f429discovery.cfg -c \
> >>>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
> >>>
> >>> -- setup kernel load bootargs at u-boot
> >>> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
> >>>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
> >>> U-Boot > loady;bootm
> >>> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
> >>>
> >>
> >>
> >> Thanks for these informations
> >> I was able to load and boot DTB and uImage directly in SDRAM as you suggested,
> >> i saw Linux logo and kernel log on the STM32F429-disco display,
> >> but i can't reach the login.
> >>
> >> The last kernel log i got is :
> >>
> >> Starting kernel ...
> >>
> >> [    0.000000] Booting Linux on physical CPU 0x0
> >> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
> >> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
> >> [    0.000000] CPU: unknown data cache, unknown instruction cache
> >> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
> >> [    0.000000] Zone ranges:
> >> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
> >> [    0.000000] Movable zone start for each node
> >> [    0.000000] Early memory node ranges
> >>
> >> [...]
> >>
> >> [    2.637564] printk: console [ttySTM0] enabled
> >> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
> >> [    2.758986] spi_stm32 40015000.spi: driver initialized
> >> [    2.795733] i2c /dev entries driver
> >> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
> >> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
> >> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
> >> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
> >> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
> >> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
> >> [    3.765208] Console: switching to colour frame buffer device 30x40
> >> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
> >> [    4.212737] Freeing unused kernel memory: 324K
> >> [    4.287300] This architecture does not have kernel memory protection.
> >> [    4.401202] Run /linuxrc as init process
> >> [    4.478622]   with arguments:
> >> [    4.555069]     /linuxrc
> >> [    4.595406]   with environment:
> >> [    4.672213]     HOME=/
> >> [    4.712511]     TERM=linux
> >> [  206.785289] random: crng init done
> >
> > I guess you didn't add the rootfs to uImage I sent you.
>
> I do use your rootfs
>
> > Could you post all the logs from u-boot startup to kernel log end.
>
>
> U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)
>
> DRAM:  8 MiB
> Flash: 2 MiB
> Loading Environment from Flash... OK
> In:    serial@40011000
> Out:   serial@40011000
> Err:   serial@40011000
> Hit any key to stop autoboot:  0
> U-Boot >    setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/lin'

It seems bootargs are broken here.
should be setenv bootargs 'console=tty0 console=ttySTM0,115200
root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'

> U-Boot >
> U-Boot >
> U-Boot > setenv loadaddr 0x90400000
> U-Boot > loady
> ## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...
> CxyzModem - CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 7 retries
> ## Total Size      = 0x00004cad = 19629 Bytes
> U-Boot > setenv loadaddr 0x90406000
> U-Boot > loady
> ## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...
> C- CRC mode, 12453(SOH)/0(STX)/0(CAN) packets, 4 retries
> ## Total Size      = 0x00185140 = 1593664 Bytes
> U-Boot > bootm 0x90406000 - 0x90400000
> ## Booting kernel from Legacy Image at 90406000 ...
>    Image Name:   Linux-5.13.0-rc1-00082-g9dbbd5cb
>    Image Type:   ARM Linux Kernel Image (uncompressed)
>    Data Size:    1593600 Bytes = 1.5 MiB
>    Load Address: 90008000
>    Entry Point:  90008000
>    Verifying Checksum ... OK
> ## Flattened Device Tree blob at 90400000
>    Booting using the fdt blob at 0x90400000
>    Loading Kernel Image
>    Loading Device Tree to 905b9000, end 905c0cac ... OK
>
> Starting kernel ...
>
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
> [    0.000000] CPU: unknown data cache, unknown instruction cache
> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
> [    0.000000] Zone ranges:
> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
> [    0.000000] Movable zone start for each node
> [    0.000000] Early memory node ranges
> [    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
> [    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
> [    0.000000] On node 0 totalpages: 2048
> [    0.000000]   Normal zone: 16 pages used for memmap
> [    0.000000]   Normal zone: 0 pages reserved
> [    0.000000]   Normal zone: 2048 pages, LIFO batch:0
> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
> [    0.000000] pcpu-alloc: [0] 0
> [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
> [    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdin2

ditto

> [    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> [    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
> [    0.000000] Memory: 5264K/8192K available (1372K kernel code, 302K rwdata, 516K rodata,)
> [    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
> [    0.000000] rcu: Preemptible hierarchical RCU implementation.
> [    0.000000] rcu:     RCU event tracing is enabled.
> [    0.000000]  Trampoline variant of Tasks RCU enabled.
> [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
> [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
> [    0.000000] /soc/interrupt-controller@40013c00: bank0
> [    0.000000] random: get_random_bytes called from start_kernel+0x203/0x370 with crng_ini0
> [    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idls
> [    0.000000] ARM System timer initialized as clocksource
> [    0.000026] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
> [    0.000665] timer@40000c00: STM32 sched_clock registered
> [    0.001275] Switching to timer-based delay loop, resolution 11ns
> [    0.001712] timer@40000c00: STM32 delay timer registered
> [    0.002253] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_is
> [    0.003076] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
> [    0.014135] Console: colour dummy device 80x30
> [    0.062375] printk: console [tty0] enabled
> [    0.063843] Calibrating delay loop (skipped), value calculated using timer frequency.. )
> [    0.066453] pid_max: default: 4096 minimum: 301
> [    0.071393] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> [    0.073734] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> [    0.104759] rcu: Hierarchical SRCU implementation.
> [    0.111552] devtmpfs: initialized
> [    0.339332] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:s
> [    0.341835] pinctrl core: initialized pinctrl subsystem
> [    0.658423] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
> [    0.680505] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
> [    0.689824] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
> [    0.699409] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
> [    0.708775] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
> [    0.718094] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
> [    0.727535] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
> [    0.736953] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
> [    0.746404] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
> [    0.756098] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
> [    0.765436] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
> [    0.774870] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
> [    0.776730] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
> [    0.997446] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
> [    1.029604] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
> [    1.043098] clocksource: Switched to clocksource timer@40000c00
> [    1.358086] workingset: timestamp_bits=30 max_order=11 bucket_order=0
> [    1.632751] io scheduler mq-deadline registered
> [    1.634287] io scheduler kyber registered
> [    1.650574] STM32 USART driver initialized
> [    1.661272] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000)t
> [    2.603317] random: fast init done
> [    2.637564] printk: console [ttySTM0] enabled
> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
> [    2.758986] spi_stm32 40015000.spi: driver initialized
> [    2.795733] i2c /dev entries driver
> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
> [    3.765208] Console: switching to colour frame buffer device 30x40
> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
> [    4.212737] Freeing unused kernel memory: 324K
> [    4.287300] This architecture does not have kernel memory protection.
> [    4.401202] Run /linuxrc as init process
> [    4.478622]   with arguments:
> [    4.555069]     /linuxrc
> [    4.595406]   with environment:
> [    4.672213]     HOME=/
> [    4.712511]     TERM=linux
> [  206.785289] random: crng init done
>
>
> >
> > If possible, you can try my suggestion.
> > - tar -jxf stm32_rootfs.tar.bz2
> > - add stm32_rootfs to your kernel config( enable initramfs)
>
> As explained above, that's what i did
>
> > - make O=YOUR_KERNEL_OUT zImage dtbs LOADADDR=0x90008000
>
>
>
> > - create itb file (combine dtb and kernel, initramfs) by mkimage
> >   ./mkimage -f stm32.its stm32.itb
>
> I didn't use .itb file, but directly uImage loaded @0x90406000 and stm32f429-disco.dtb loaded @0x90400000

It's fine with manual load dtb and uImage.

>
> How do you generate .its file ?

I refer to u-boot doc , U-BOOT-SOURCE/doc/uImage.FIT/kernel.its
you can just change the PATH('data = ' filed) of my stm32.its.
you can correct bootargs in u-boot, try again

good luck.

Thanks

Best Regards
Dillon

>
>
> >   (before above command, make sure you correct stm32.its adapt to your env)
> >
> > This process will make u-boot to load the kernel more simple.
> >
> > Thanks.
> >
> > Best Regards.
> > Dillon
> >
> >
> >>
> >>
> >> I can't test your I2C patch.
> >>
> >> Patrice
> >>
> >>
> >>> -- setup ts_calibrate running env on stm32f429-disco
> >>> / # export TSLIB_CONFFILE=/etc/ts.conf
> >>> / # export TSLIB_TSDEVICE=/dev/input/event0
> >>> / # export TSLIB_CONSOLEDEVICE=none
> >>> / # export TSLIB_FBDEVICE=/dev/fb0
> >>>
> >>> -- clear screen
> >>> / # ./fb
> >>>
> >>> -- run ts_calibrate
> >>> / # ts_calibrate
> >>> (you can calibrate touchscreen now, and get below errors)
> >>>
> >>> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
> >>> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
> >>> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
> >>> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
> >>>
> >>> ...
> >>> with i2c patch applied, you will find below logs:
> >>>
> >>> RAW---------------------> 3164 908 183 118.110884
> >>> TS_READ_RAW----> x = 3164, y =908, pressure = 183
> >>> RAW---------------------> 3166 922 126 118.138946
> >>> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
> >>> ....
> >>>
> >>> files link:
> >>> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
> >>>
> >>>
> >>>
> >>>
> >>> Dillon Min (4):
> >>>   drm/panel: Add ilitek ili9341 panel driver
> >>>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
> >>>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
> >>>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
> >>>     kernel startup
> >>>
> >>>  drivers/clk/clk-stm32f4.c                    |   10 +-
> >>>  drivers/gpu/drm/panel/Kconfig                |   12 +
> >>>  drivers/gpu/drm/panel/Makefile               |    1 +
> >>>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
> >>>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
> >>>  5 files changed, 1310 insertions(+), 10 deletions(-)
> >>>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> >>>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-31 14:29       ` Dillon Min
@ 2021-05-31 14:58         ` Patrice CHOTARD
  2021-06-01  3:28           ` Dillon Min
  0 siblings, 1 reply; 20+ messages in thread
From: Patrice CHOTARD @ 2021-05-31 14:58 UTC (permalink / raw)
  To: Dillon Min
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

[-- Attachment #1: Type: text/plain, Size: 15608 bytes --]

Hi Dillon

On 5/31/21 4:29 PM, Dillon Min wrote:
> Hi Patrice
> 
> On Mon, May 31, 2021 at 9:51 PM Patrice CHOTARD
> <patrice.chotard@foss.st.com> wrote:
>>
>>
>>
>> On 5/31/21 3:38 PM, Dillon Min wrote:
>>> Hi Patrice
>>>
>>> Thanks for your time to test my patch.
>>>
>>> On Mon, May 31, 2021 at 9:20 PM Patrice CHOTARD
>>> <patrice.chotard@foss.st.com> wrote:
>>>>
>>>> Hi Dillon
>>>>
>>>>
>>>>
>>>> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
>>>>> From: Dillon Min <dillon.minfei@gmail.com>
>>>>>
>>>>> This seriese fix three i2c/clk bug for stm32 f4/f7
>>>>> - kernel runing in sdram, i2c driver get data timeout
>>>>> - ltdc clk turn off after kernel console active
>>>>> - kernel hang in set ltdc clock rate
>>>>>
>>>>> clk bug found on stm32f429/f469-disco board
>>>>>
>>>>> Hi Patrice:
>>>>> below is the guide to verify the patch:
>>>>>
>>>>> setup test env with following files(link at below 'files link'):
>>>>> [1] u-boot-dtb.bin
>>>>> [2] rootfs zip file (used in kernel initramfs)
>>>>> [3] u-boot's mkimage to create itb file
>>>>> [4] kernel config file
>>>>> [5] my itb with-or-without i2c patch
>>>>>
>>>>> This patch based on kernel commit:
>>>>> 88b06399c9c766c283e070b022b5ceafa4f63f19
>>>>>
>>>>> Note:
>>>>> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
>>>>> get accepted. it's used to setup touch screen calibration, then test i2c.
>>>>>
>>>>> create itb file(please correct path of 'data'):
>>>>> ./mkimage -f stm32.its stm32.itb
>>>>>
>>>>> HW setup:
>>>>> console:
>>>>>        PA9, PA10
>>>>>        usart0
>>>>>        serial@40011000
>>>>>        115200 8n1
>>>>>
>>>>> -- flash u-boot.bin to stm32f429-disco on PC
>>>>> $ sudo openocd -f board/stm32f429discovery.cfg -c \
>>>>>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
>>>>>
>>>>> -- setup kernel load bootargs at u-boot
>>>>> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
>>>>>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
>>>>> U-Boot > loady;bootm
>>>>> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
>>>>>
>>>>
>>>>
>>>> Thanks for these informations
>>>> I was able to load and boot DTB and uImage directly in SDRAM as you suggested,
>>>> i saw Linux logo and kernel log on the STM32F429-disco display,
>>>> but i can't reach the login.
>>>>
>>>> The last kernel log i got is :
>>>>
>>>> Starting kernel ...
>>>>
>>>> [    0.000000] Booting Linux on physical CPU 0x0
>>>> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
>>>> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
>>>> [    0.000000] CPU: unknown data cache, unknown instruction cache
>>>> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
>>>> [    0.000000] Zone ranges:
>>>> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
>>>> [    0.000000] Movable zone start for each node
>>>> [    0.000000] Early memory node ranges
>>>>
>>>> [...]
>>>>
>>>> [    2.637564] printk: console [ttySTM0] enabled
>>>> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
>>>> [    2.758986] spi_stm32 40015000.spi: driver initialized
>>>> [    2.795733] i2c /dev entries driver
>>>> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
>>>> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
>>>> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
>>>> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
>>>> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
>>>> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
>>>> [    3.765208] Console: switching to colour frame buffer device 30x40
>>>> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
>>>> [    4.212737] Freeing unused kernel memory: 324K
>>>> [    4.287300] This architecture does not have kernel memory protection.
>>>> [    4.401202] Run /linuxrc as init process
>>>> [    4.478622]   with arguments:
>>>> [    4.555069]     /linuxrc
>>>> [    4.595406]   with environment:
>>>> [    4.672213]     HOME=/
>>>> [    4.712511]     TERM=linux
>>>> [  206.785289] random: crng init done
>>>
>>> I guess you didn't add the rootfs to uImage I sent you.
>>
>> I do use your rootfs
>>
>>> Could you post all the logs from u-boot startup to kernel log end.
>>
>>
>> U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)
>>
>> DRAM:  8 MiB
>> Flash: 2 MiB
>> Loading Environment from Flash... OK
>> In:    serial@40011000
>> Out:   serial@40011000
>> Err:   serial@40011000
>> Hit any key to stop autoboot:  0
>> U-Boot >    setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/lin'
> 
> It seems bootargs are broken here.
> should be setenv bootargs 'console=tty0 console=ttySTM0,115200
> root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'

It's just a copy/paste issue from my minicom window to my mailer, 
but the bootargs is correct ;-)

See a correct U-boot/kernel log in attached.


> 
>> U-Boot >
>> U-Boot >
>> U-Boot > setenv loadaddr 0x90400000
>> U-Boot > loady
>> ## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...
>> CxyzModem - CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 7 retries
>> ## Total Size      = 0x00004cad = 19629 Bytes
>> U-Boot > setenv loadaddr 0x90406000
>> U-Boot > loady
>> ## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...
>> C- CRC mode, 12453(SOH)/0(STX)/0(CAN) packets, 4 retries
>> ## Total Size      = 0x00185140 = 1593664 Bytes
>> U-Boot > bootm 0x90406000 - 0x90400000
>> ## Booting kernel from Legacy Image at 90406000 ...
>>    Image Name:   Linux-5.13.0-rc1-00082-g9dbbd5cb
>>    Image Type:   ARM Linux Kernel Image (uncompressed)
>>    Data Size:    1593600 Bytes = 1.5 MiB
>>    Load Address: 90008000
>>    Entry Point:  90008000
>>    Verifying Checksum ... OK
>> ## Flattened Device Tree blob at 90400000
>>    Booting using the fdt blob at 0x90400000
>>    Loading Kernel Image
>>    Loading Device Tree to 905b9000, end 905c0cac ... OK
>>
>> Starting kernel ...
>>
>> [    0.000000] Booting Linux on physical CPU 0x0
>> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
>> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
>> [    0.000000] CPU: unknown data cache, unknown instruction cache
>> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
>> [    0.000000] Zone ranges:
>> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
>> [    0.000000] Movable zone start for each node
>> [    0.000000] Early memory node ranges
>> [    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
>> [    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
>> [    0.000000] On node 0 totalpages: 2048
>> [    0.000000]   Normal zone: 16 pages used for memmap
>> [    0.000000]   Normal zone: 0 pages reserved
>> [    0.000000]   Normal zone: 2048 pages, LIFO batch:0
>> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
>> [    0.000000] pcpu-alloc: [0] 0
>> [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
>> [    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdin2
> 
> ditto

same explanation as above, the command line displayed is truncated, but it is the one expected.


> 
>> [    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>> [    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>> [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
>> [    0.000000] Memory: 5264K/8192K available (1372K kernel code, 302K rwdata, 516K rodata,)
>> [    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
>> [    0.000000] rcu: Preemptible hierarchical RCU implementation.
>> [    0.000000] rcu:     RCU event tracing is enabled.
>> [    0.000000]  Trampoline variant of Tasks RCU enabled.
>> [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
>> [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
>> [    0.000000] /soc/interrupt-controller@40013c00: bank0
>> [    0.000000] random: get_random_bytes called from start_kernel+0x203/0x370 with crng_ini0
>> [    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idls
>> [    0.000000] ARM System timer initialized as clocksource
>> [    0.000026] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
>> [    0.000665] timer@40000c00: STM32 sched_clock registered
>> [    0.001275] Switching to timer-based delay loop, resolution 11ns
>> [    0.001712] timer@40000c00: STM32 delay timer registered
>> [    0.002253] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_is
>> [    0.003076] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
>> [    0.014135] Console: colour dummy device 80x30
>> [    0.062375] printk: console [tty0] enabled
>> [    0.063843] Calibrating delay loop (skipped), value calculated using timer frequency.. )
>> [    0.066453] pid_max: default: 4096 minimum: 301
>> [    0.071393] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>> [    0.073734] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>> [    0.104759] rcu: Hierarchical SRCU implementation.
>> [    0.111552] devtmpfs: initialized
>> [    0.339332] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:s
>> [    0.341835] pinctrl core: initialized pinctrl subsystem
>> [    0.658423] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
>> [    0.680505] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
>> [    0.689824] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
>> [    0.699409] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
>> [    0.708775] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
>> [    0.718094] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
>> [    0.727535] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
>> [    0.736953] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
>> [    0.746404] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
>> [    0.756098] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
>> [    0.765436] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
>> [    0.774870] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
>> [    0.776730] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
>> [    0.997446] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
>> [    1.029604] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
>> [    1.043098] clocksource: Switched to clocksource timer@40000c00
>> [    1.358086] workingset: timestamp_bits=30 max_order=11 bucket_order=0
>> [    1.632751] io scheduler mq-deadline registered
>> [    1.634287] io scheduler kyber registered
>> [    1.650574] STM32 USART driver initialized
>> [    1.661272] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000)t
>> [    2.603317] random: fast init done
>> [    2.637564] printk: console [ttySTM0] enabled
>> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
>> [    2.758986] spi_stm32 40015000.spi: driver initialized
>> [    2.795733] i2c /dev entries driver
>> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
>> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
>> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
>> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
>> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
>> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
>> [    3.765208] Console: switching to colour frame buffer device 30x40
>> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
>> [    4.212737] Freeing unused kernel memory: 324K
>> [    4.287300] This architecture does not have kernel memory protection.
>> [    4.401202] Run /linuxrc as init process
>> [    4.478622]   with arguments:
>> [    4.555069]     /linuxrc
>> [    4.595406]   with environment:
>> [    4.672213]     HOME=/
>> [    4.712511]     TERM=linux
>> [  206.785289] random: crng init done
>>
>>
>>>
>>> If possible, you can try my suggestion.
>>> - tar -jxf stm32_rootfs.tar.bz2
>>> - add stm32_rootfs to your kernel config( enable initramfs)
>>
>> As explained above, that's what i did
>>
>>> - make O=YOUR_KERNEL_OUT zImage dtbs LOADADDR=0x90008000
>>
>>
>>
>>> - create itb file (combine dtb and kernel, initramfs) by mkimage
>>>   ./mkimage -f stm32.its stm32.itb
>>
>> I didn't use .itb file, but directly uImage loaded @0x90406000 and stm32f429-disco.dtb loaded @0x90400000
> 
> It's fine with manual load dtb and uImage.
> 
>>
>> How do you generate .its file ?
> 
> I refer to u-boot doc , U-BOOT-SOURCE/doc/uImage.FIT/kernel.its
> you can just change the PATH('data = ' filed) of my stm32.its.
> you can correct bootargs in u-boot, try again
> 
> good luck.
> 
> Thanks
> 
> Best Regards
> Dillon
> 
>>
>>
>>>   (before above command, make sure you correct stm32.its adapt to your env)
>>>
>>> This process will make u-boot to load the kernel more simple.
>>>
>>> Thanks.
>>>
>>> Best Regards.
>>> Dillon
>>>
>>>
>>>>
>>>>
>>>> I can't test your I2C patch.
>>>>
>>>> Patrice
>>>>
>>>>
>>>>> -- setup ts_calibrate running env on stm32f429-disco
>>>>> / # export TSLIB_CONFFILE=/etc/ts.conf
>>>>> / # export TSLIB_TSDEVICE=/dev/input/event0
>>>>> / # export TSLIB_CONSOLEDEVICE=none
>>>>> / # export TSLIB_FBDEVICE=/dev/fb0
>>>>>
>>>>> -- clear screen
>>>>> / # ./fb
>>>>>
>>>>> -- run ts_calibrate
>>>>> / # ts_calibrate
>>>>> (you can calibrate touchscreen now, and get below errors)
>>>>>
>>>>> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
>>>>> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
>>>>> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
>>>>> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
>>>>>
>>>>> ...
>>>>> with i2c patch applied, you will find below logs:
>>>>>
>>>>> RAW---------------------> 3164 908 183 118.110884
>>>>> TS_READ_RAW----> x = 3164, y =908, pressure = 183
>>>>> RAW---------------------> 3166 922 126 118.138946
>>>>> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
>>>>> ....
>>>>>
>>>>> files link:
>>>>> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Dillon Min (4):
>>>>>   drm/panel: Add ilitek ili9341 panel driver
>>>>>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
>>>>>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
>>>>>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
>>>>>     kernel startup
>>>>>
>>>>>  drivers/clk/clk-stm32f4.c                    |   10 +-
>>>>>  drivers/gpu/drm/panel/Kconfig                |   12 +
>>>>>  drivers/gpu/drm/panel/Makefile               |    1 +
>>>>>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
>>>>>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
>>>>>  5 files changed, 1310 insertions(+), 10 deletions(-)
>>>>>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
>>>>>

[-- Attachment #2: uboot_kernel_log.txt --]
[-- Type: text/plain, Size: 9937 bytes --]


U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)                                                          
                                                                                                           
DRAM:  8 MiB                                                                                               
Flash: 2 MiB                                                                                               
Loading Environment from Flash... OK                                                                       
In:    serial@40011000                                                                                     
Out:   serial@40011000                                                                                     
Err:   serial@40011000                                                                                     
Hit any key to stop autoboot:  0                                                                           
U-Boot >  setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
U-Boot > setenv loadaddr 0x90400000                                                                        
U-Boot > loady                                                                                             
## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...                                       
CyzModem - CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 6 retries                                             
## Total Size      = 0x00004cad = 19629 Bytes                                                              
U-Boot > setenv loadaddr 0x90406000                                                                        
U-Boot > loady                                                                                             
## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...                                       
CyzModem - CRC mode, 12453(SOH)/0(STX)/0(CAN) packets, 4 retries                                           
## Total Size      = 0x00185140 = 1593664 Bytes                                                            
U-Boot > bootm 0x90406000 - 0x90400000                                                                     
## Booting kernel from Legacy Image at 90406000 ...                                                        
   Image Name:   Linux-5.13.0-rc1-00082-g9dbbd5cb                                                          
   Image Type:   ARM Linux Kernel Image (uncompressed)                                                     
   Data Size:    1593600 Bytes = 1.5 MiB                                                                   
   Load Address: 90008000                                                                                  
   Entry Point:  90008000                                                                                  
   Verifying Checksum ... OK                                                                               
## Flattened Device Tree blob at 90400000                                                                  
   Booting using the fdt blob at 0x90400000                                                                
   Loading Kernel Image                                                                                    
   Loading Device Tree to 905b9000, end 905c0cac ... OK                                                    
                                                                                                           
Starting kernel ...
                                                                                                           
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme.st.com) (arm-buildroot-uclinux-uclibcgnueabi1
[    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: unknown data cache, unknown instruction cache
[    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] On node 0 totalpages: 2048
[    0.000000]   Normal zone: 16 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 2048 pages, LIFO batch:0
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
[    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2
[    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 5264K/8192K available (1372K kernel code, 302K rwdata, 516K rodata, 324K init, 119K bss, 2928K reserved, 0K cma-)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000]  Trampoline variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] /soc/interrupt-controller@40013c00: bank0
[    0.000000] random: get_random_bytes called from start_kernel+0x203/0x370 with crng_init=0
[    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 331816030 ns
[    0.000000] ARM System timer initialized as clocksource
[    0.000026] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
[    0.000665] timer@40000c00: STM32 sched_clock registered
[    0.001275] Switching to timer-based delay loop, resolution 11ns
[    0.001712] timer@40000c00: STM32 delay timer registered
[    0.002253] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 21236227187 ns
[    0.003076] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
[    0.014135] Console: colour dummy device 80x30
[    0.062375] printk: console [tty0] enabled
[    0.063843] Calibrating delay loop (skipped), value calculated using timer frequency.. 180.00 BogoMIPS (lpj=900000)
[    0.066453] pid_max: default: 4096 minimum: 301
[    0.071393] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.073734] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.104759] rcu: Hierarchical SRCU implementation.
[    0.111552] devtmpfs: initialized
[    0.339332] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.341835] pinctrl core: initialized pinctrl subsystem
[    0.658423] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
[    0.680505] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
[    0.689824] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
[    0.699409] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
[    0.708775] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
[    0.718094] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
[    0.727535] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
[    0.736953] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
[    0.746404] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
[    0.756098] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
[    0.765436] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
[    0.774870] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
[    0.776730] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
[    0.997446] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
[    1.029604] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
[    1.043098] clocksource: Switched to clocksource timer@40000c00
[    1.358086] workingset: timestamp_bits=30 max_order=11 bucket_order=0
[    1.632751] io scheduler mq-deadline registered
[    1.634287] io scheduler kyber registered
[    1.650574] STM32 USART driver initialized
[    1.661272] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000) is a stm32-usart
[    2.603317] random: fast init done
[    2.637564] printk: console [ttySTM0] enabled
[    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
[    2.758986] spi_stm32 40015000.spi: driver initialized
[    2.795733] i2c /dev entries driver
[    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
[    2.922030] stmpe-ts stmpe-ts: DMA mask not set
[    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts/input/input0
[    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
[    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on minor 0
[    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
[    3.765213] Console: switching to colour frame buffer device 30x40
[    4.014240] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffer device
[    4.212714] Freeing unused kernel memory: 324K
[    4.287271] This architecture does not have kernel memory protection.
[    4.401197] Run /linuxrc as init process
[    4.478612]   with arguments:
[    4.555066]     /linuxrc
[    4.595404]   with environment:
[    4.672212]     HOME=/
[    4.712511]     TERM=linux
[  206.785288] random: crng init done

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver
  2021-05-31 13:39     ` Dillon Min
@ 2021-06-01  2:31       ` Dillon Min
  0 siblings, 0 replies; 20+ messages in thread
From: Dillon Min @ 2021-06-01  2:31 UTC (permalink / raw)
  To: Patrice CHOTARD
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

Hi Patrice

On Mon, May 31, 2021 at 9:39 PM Dillon Min <dillon.minfei@gmail.com> wrote:
>
> On Mon, May 31, 2021 at 9:15 PM Patrice CHOTARD
> <patrice.chotard@foss.st.com> wrote:
> >
> > Hi Dillon
> >
> > When trying to applying this patch using "git am --3 <patch>"  i got this error :
> >
> > error: cannot convert from y to UTF-8
> > fatal: could not parse patch
> >
> > Whereas i got no similar error with the other patch 2/3 and 4.
> >
> > I find a way to apply it anyway.
>
> Sorry for the inconvenience, I will double verify the 'git am' process
> on this patch later.

I can't reproduce this on my side.

fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$ git --version
git version 2.7.4
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$ git am --3
../miss-c/v1/0001-drm-panel-Add-ilitek-ili9341-panel-driver.patch
Applying: drm/panel: Add ilitek ili9341 panel driver
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$ git am --3
../miss-c/v1/0002-i2c-stm32f4-Fix-stmpe811-get-xyz-data-timeout-issue.patch
Applying: i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$ git am --3
../miss-c/v1/0003-clk-stm32-Fix-stm32f429-s-ltdc-driver-hang-in-set-cl.patch
Applying: clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$ git am --3
../miss-c/v1/0004-clk-stm32-Fix-ltdc-s-clock-turn-off-by-clk_disable_u.patch
Applying: clk: stm32: Fix ltdc's clock turn off by
clk_disable_unused() after kernel startup
fmin@fmin-OptiPlex-7060:~/work/kernel/up/linux$ git log
commit bbd74144f015b7a81d728f4c942925c74b415b97
Author: Dillon Min <dillon.minfei@gmail.com>
Date:   Fri May 14 18:18:45 2021 +0800

    clk: stm32: Fix ltdc's clock turn off by clk_disable_unused()
after kernel startup

    stm32's clk driver register two ltdc gate clk to clk core by
    clk_hw_register_gate() and clk_hw_register_composite()

    first: 'stm32f429_gates[]', clk name is 'ltdc', which no user to use.
    second: 'stm32f429_aux_clk[]', clk name is 'lcd-tft', used by ltdc driver

    both of them point to the same offset of stm32's RCC register. after
    kernel enter console, clk core turn off ltdc's clk as 'stm32f429_gates[]'
    is no one to use. but, actually 'stm32f429_aux_clk[]' is in use.

    Fixes: daf2d117cbca ("clk: stm32f4: Add lcd-tft clock")
    Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
    Acked-by: Stephen Boyd <sboyd@kernel.org>
    Link: https://lore.kernel.org/linux-arm-kernel/1590564453-24499-7-git-send-email-dillon.minfei@gmail.com/

commit 9923957735ad0ae3e9da7f35f9bf83d6882499c6
Author: Dillon Min <dillon.minfei@gmail.com>
Date:   Fri May 14 18:15:06 2021 +0800

    clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate

    This is due to misuse ‘PLL_VCO_SAI' and'PLL_SAI' in clk-stm32f4.c
    'PLL_SAI' is 2, 'PLL_VCO_SAI' is 7(defined in
    include/dt-bindings/clock/stm32fx-clock.h).

    'post_div' point to 'post_div_data[]', 'post_div->pll_num'
    is PLL_I2S or PLL_SAI.

    'clks[PLL_VCO_SAI]' has valid 'struct clk_hw* ' return
    from stm32f4_rcc_register_pll() but, at line 1777 of
    driver/clk/clk-stm32f4.c, use the 'clks[post_div->pll_num]',
    equal to 'clks[PLL_SAI]', this is invalid array member at that time.

    Fixes: 517633ef630e ("clk: stm32f4: Add post divisor for I2S & SAI PLLs")
    Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
    Acked-by: Stephen Boyd <sboyd@kernel.org>
    Link: https://lore.kernel.org/linux-arm-kernel/1590564453-24499-6-git-send-email-dillon.minfei@gmail.com/

commit eeade16ed602079c9f469692a543ff00fd527a1c
Author: Dillon Min <dillon.minfei@gmail.com>
Date:   Fri May 14 17:29:47 2021 +0800

    i2c: stm32f4: Fix stmpe811 get xyz data timeout issue

    As stm32f429's internal flash is 2Mbytes and compiled kernel
    image bigger than 2Mbytes, so we have to load kernel image
    to sdram on stm32f429-disco board which has 8Mbytes sdram space.

    based on above context, as you knows kernel running on external
    sdram is more slower than internal flash. besides, we need read 4
    bytes to get touch screen xyz(x, y, pressure) coordinate data in
    stmpe811 interrupt.

    so, in stm32f4_i2c_handle_rx_done, as i2c read slower than running
    in xip mode, have to adjust 'STOP/START bit set position' from last
    two bytes to last one bytes. else, will get i2c timeout in reading
    touch screen coordinate.

    to not bring in side effect, introduce IIC_LAST_BYTE_POS to support xip
    kernel or zImage.

    Fixes: 62817fc8d282 ("i2c: stm32f4: add driver")
    Link: https://lore.kernel.org/lkml/1591709203-12106-5-git-send-email-dillon.minfei@gmail.com/
    Signed-off-by: Dillon Min <dillon.minfei@gmail.com>

commit 8de9a39a4f6e793f99a23fe7105a3dd7d997058b
Author: Dillon Min <dillon.minfei@gmail.com>
Date:   Fri May 14 17:20:17 2021 +0800

    drm/panel: Add ilitek ili9341 panel driver

    This driver combine tiny/ili9341.c mipi_dbi_interface driver
    with mipi_dpi_interface driver, can support ili9341 with serial
    mode or parallel rgb interface mode by register configuration.

    Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
    Link: https://lore.kernel.org/lkml/1590378348-8115-7-git-send-email-dillon.minfei@gmail.com/
    Signed-off-by: Dillon Min <dillon.minfei@gmail.com>

commit c2131f7e73c9e9365613e323d65c7b9e5b910f56
Merge: 36c795513a88 1ab19c5de4c5
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Mon May 31 05:57:22 2021 -1000

    Merge tag 'gfs2-v5.13-rc2-fixes' of
git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

    Pull gfs2 fixes from Andreas Gruenbacher:
     "Various gfs2 fixes"

    * tag 'gfs2-v5.13-rc2-fixes' of
git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
      gfs2: Fix use-after-free in gfs2_glock_shrink_scan
      gfs2: Fix mmap locking for write faults
      gfs2: Clean up revokes on normal withdraws
      gfs2: fix a deadlock on withdraw-during-mount
      gfs2: fix scheduling while atomic bug in glocks
      gfs2: Fix I_NEW check in gfs2_dinode_in
      gfs2: Prevent direct-I/O write fallback errors from getting lost


Best Regards
Dillon

>
> Thanks.
>
> Best Regards
> Dillon
>
> >
> > Patrice
> >
> >
> > On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> > > From: Dillon Min <dillon.minfei@gmail.com>
> > >
> > > This driver combine tiny/ili9341.c mipi_dbi_interface driver
> > > with mipi_dpi_interface driver, can support ili9341 with serial
> > > mode or parallel rgb interface mode by register configuration.
> > >
> > > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > > Link: https://lore.kernel.org/lkml/1590378348-8115-7-git-send-email-dillon.minfei@gmail.com/
> > > Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> > > ---
> > >  drivers/gpu/drm/panel/Kconfig                |   12 +
> > >  drivers/gpu/drm/panel/Makefile               |    1 +
> > >  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
> > >  3 files changed, 1298 insertions(+)
> > >  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > >
> > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> > > index 4894913936e9..e4babba17864 100644
> > > --- a/drivers/gpu/drm/panel/Kconfig
> > > +++ b/drivers/gpu/drm/panel/Kconfig
> > > @@ -123,6 +123,18 @@ config DRM_PANEL_ILITEK_IL9322
> > >         Say Y here if you want to enable support for Ilitek IL9322
> > >         QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
> > >
> > > +config DRM_PANEL_ILITEK_ILI9341
> > > +     tristate "Ilitek ILI9341 240x320 QVGA panels"
> > > +     depends on OF && SPI
> > > +     depends on DRM_KMS_HELPER
> > > +     depends on DRM_KMS_CMA_HELPER
> > > +     depends on BACKLIGHT_CLASS_DEVICE
> > > +     select DRM_MIPI_DBI
> > > +     help
> > > +       Say Y here if you want to enable support for Ilitek IL9341
> > > +       QVGA (240x320) RGB panels. support serial & parallel rgb
> > > +       interface.
> > > +
> > >  config DRM_PANEL_ILITEK_ILI9881C
> > >       tristate "Ilitek ILI9881C-based panels"
> > >       depends on OF
> > > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> > > index cae4d976c069..0ecde184665d 100644
> > > --- a/drivers/gpu/drm/panel/Makefile
> > > +++ b/drivers/gpu/drm/panel/Makefile
> > > @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
> > >  obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
> > >  obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
> > >  obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
> > > +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
> > >  obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
> > >  obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
> > >  obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
> > > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > > new file mode 100644
> > > index 000000000000..f84983cbb250
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> > > @@ -0,0 +1,1285 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * Ilitek ILI9341 TFT LCD drm_panel driver.
> > > + *
> > > + * This panel can be configured to support:
> > > + * - 16-bit parallel RGB interface
> > > + * - 18-bit parallel RGB interface
> > > + * - 4-line serial spi interface
> > > + *
> > > + * Copyright (C) 2020 Dillon Min <dillon.minfei@gmail.com>
> > > + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
> > > + */
> > > +
> > > +#include <linux/bitops.h>
> > > +#include <linux/gpio/consumer.h>
> > > +#include <linux/module.h>
> > > +#include <linux/of_device.h>
> > > +#include <linux/regulator/consumer.h>
> > > +#include <linux/spi/spi.h>
> > > +#include <linux/delay.h>
> > > +#include <video/mipi_display.h>
> > > +#include <drm/drm_mipi_dbi.h>
> > > +#include <drm/drm_gem_framebuffer_helper.h>
> > > +#include <drm/drm_gem_cma_helper.h>
> > > +#include <drm/drm_fb_helper.h>
> > > +#include <drm/drm_gem_atomic_helper.h>
> > > +#include <drm/drm_atomic_helper.h>
> > > +
> > > +#include <drm/drm_drv.h>
> > > +#include <drm/drm_modes.h>
> > > +#include <drm/drm_panel.h>
> > > +#include <drm/drm_print.h>
> > > +
> > > +#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
> > > +#define ILI9341_FRC            0xb1   /* Frame Rate Control register */
> > > +#define ILI9341_DFC            0xb6   /* Display Function Control register */
> > > +#define ILI9341_POWER1         0xc0   /* Power Control 1 register */
> > > +#define ILI9341_POWER2         0xc1   /* Power Control 2 register */
> > > +#define ILI9341_VCOM1          0xc5   /* VCOM Control 1 register */
> > > +#define ILI9341_VCOM2          0xc7   /* VCOM Control 2 register */
> > > +#define ILI9341_POWERA         0xcb   /* Power control A register */
> > > +#define ILI9341_POWERB         0xcf   /* Power control B register */
> > > +#define ILI9341_PGAMMA         0xe0   /* Positive Gamma Correction register */
> > > +#define ILI9341_NGAMMA         0xe1   /* Negative Gamma Correction register */
> > > +#define ILI9341_DTCA           0xe8   /* Driver timing control A */
> > > +#define ILI9341_DTCB           0xea   /* Driver timing control B */
> > > +#define ILI9341_POWER_SEQ      0xed   /* Power on sequence register */
> > > +#define ILI9341_3GAMMA_EN      0xf2   /* 3 Gamma enable register */
> > > +#define ILI9341_INTERFACE      0xf6   /* Interface control register */
> > > +#define ILI9341_PRC            0xf7   /* Pump ratio control register */
> > > +#define ILI9341_ETMOD               0xb7   /* Entry mode set */
> > > +
> > > +#define ILI9341_MADCTL_BGR   BIT(3)
> > > +#define ILI9341_MADCTL_MV    BIT(5)
> > > +#define ILI9341_MADCTL_MX    BIT(6)
> > > +#define ILI9341_MADCTL_MY    BIT(7)
> > > +
> > > +
> > > +#define ILI9341_POWER_B_LEN  3
> > > +#define ILI9341_POWER_SEQ_LEN        4
> > > +#define ILI9341_DTCA_LEN     3
> > > +#define ILI9341_DTCB_LEN     2
> > > +#define ILI9341_POWER_A_LEN  5
> > > +#define ILI9341_DFC_1_LEN    2
> > > +#define ILI9341_FRC_LEN              2
> > > +#define ILI9341_VCOM_1_LEN   2
> > > +#define ILI9341_DFC_2_LEN    4
> > > +#define ILI9341_COLUMN_ADDR_LEN      4
> > > +#define ILI9341_PAGE_ADDR_LEN        4
> > > +#define ILI9341_INTERFACE_LEN        3
> > > +#define ILI9341_PGAMMA_LEN   15
> > > +#define ILI9341_NGAMMA_LEN   15
> > > +#define ILI9341_CA_LEN               3
> > > +
> > > +#define ILI9341_PIXEL_DPI_16_BITS    (BIT(6)|BIT(4))
> > > +#define ILI9341_PIXEL_DPI_18_BITS    (BIT(6)|BIT(5))
> > > +#define ILI9341_GAMMA_CURVE_1                BIT(0)
> > > +#define ILI9341_IF_WE_MODE           BIT(0)
> > > +#define ILI9341_IF_BIG_ENDIAN                0x00
> > > +#define ILI9341_IF_DM_RGB            BIT(2)
> > > +#define ILI9341_IF_DM_INTERNAL               0x00
> > > +#define ILI9341_IF_DM_VSYNC          BIT(3)
> > > +#define ILI9341_IF_RM_RGB            BIT(1)
> > > +#define ILI9341_IF_RIM_RGB           0x00
> > > +
> > > +#define ILI9341_COLUMN_ADDR          0x00ef
> > > +#define ILI9341_PAGE_ADDR            0x013f
> > > +
> > > +#define ILI9341_RGB_EPL                      BIT(0)
> > > +#define ILI9341_RGB_DPL                      BIT(1)
> > > +#define ILI9341_RGB_HSPL             BIT(2)
> > > +#define ILI9341_RGB_VSPL             BIT(3)
> > > +#define ILI9341_RGB_DE_MODE          BIT(6)
> > > +#define ILI9341_RGB_DISP_PATH_MEM    BIT(7)
> > > +
> > > +#define ILI9341_DBI_VCOMH_4P6V               0x23
> > > +#define ILI9341_DBI_PWR_2_DEFAULT    0x10
> > > +#define ILI9341_DBI_PRC_NORMAL               0x20
> > > +#define ILI9341_DBI_VCOM_1_VMH_4P25V 0x3e
> > > +#define ILI9341_DBI_VCOM_1_VML_1P5V  0x28
> > > +#define ILI9341_DBI_VCOM_2_DEC_58    0x86
> > > +#define ILI9341_DBI_FRC_DIVA         0x00
> > > +#define ILI9341_DBI_FRC_RTNA         0x1b
> > > +#define ILI9341_DBI_EMS_GAS          BIT(0)
> > > +#define ILI9341_DBI_EMS_DTS          BIT(1)
> > > +#define ILI9341_DBI_EMS_GON          BIT(2)
> > > +/**
> > > + * ili9341_command - ili9341 command with optional parameter(s)
> > > + * @ili: struct ili9341
> > > + * @cmd: Command
> > > + * @seq...: Optional parameter(s)
> > > + *
> > > + * Send command to the controller.
> > > + *
> > > + * Returns:
> > > + * Zero on success, negative error code on failure.
> > > + */
> > > +#define ili9341_command(ili, cmd, seq...) \
> > > +({ \
> > > +     u8 d[] = { seq }; \
> > > +     _ili9341_command(ili, cmd, d, ARRAY_SIZE(d)); \
> > > +})
> > > +
> > > +/**
> > > + * struct ili9341_config - the system specific ILI9341 configuration
> > > + * @max_spi_speed: 10000000
> > > + */
> > > +struct ili9341_config {
> > > +     u32 max_spi_speed;
> > > +     /** @mode: the drm display mode */
> > > +     const struct drm_display_mode mode;
> > > +     /** @ca: TODO: need comments for this register */
> > > +     u8 ca[ILI9341_CA_LEN];
> > > +     /** @power_b: TODO: need comments for this register */
> > > +     u8 power_b[ILI9341_POWER_B_LEN];
> > > +     /** @power_seq: TODO: need comments for this register */
> > > +     u8 power_seq[ILI9341_POWER_SEQ_LEN];
> > > +     /** @dtca: TODO: need comments for this register */
> > > +     u8 dtca[ILI9341_DTCA_LEN];
> > > +     /** @dtcb: TODO: need comments for this register */
> > > +     u8 dtcb[ILI9341_DTCB_LEN];
> > > +     /** @power_a: TODO: need comments for this register */
> > > +     u8 power_a[ILI9341_POWER_A_LEN];
> > > +     /** @frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
> > > +     /*
> > > +      * Formula to calculate frame frequency:
> > > +      * Frame Rate=fosc/(Clocks per line x Division ratio x
> > > +      * (Lines+VBP+VFP))
> > > +      *
> > > +      * Sets the division ratio for internal clocks of Normal mode at MCU
> > > +      * interface.
> > > +      *
> > > +      * fosc : internal oscillator frequency
> > > +      * Clocks per line : RTNA setting
> > > +      * Division ratio : DIVA setting
> > > +      * Lines : total driving line number
> > > +      * VBP : back porch line number
> > > +      * VFP : front porch line number
> > > +      *
> > > +      * RTNA [4:0] Frame Rate (Hz)   RTNA [4:0] Frame Rate (Hz)
> > > +      * 1 0 0 0 0  119               1 1 0 0 0  79
> > > +      * 1 0 0 0 1  112               1 1 0 0 1  76
> > > +      * 1 0 0 1 0  106               1 1 0 1 0  73
> > > +      * 1 0 0 1 1  100               1 1 0 1 1  70(default)
> > > +      * 1 0 1 0 0  95                1 1 1 0 0  68
> > > +      * 1 0 1 0 1  90                1 1 1 0 1  65
> > > +      * 1 0 1 1 0  86                1 1 1 0 1  63
> > > +      * 1 0 1 1 1  83                1 1 1 1 1  61
> > > +      *
> > > +      * DIVA [1:0] : division ratio for internal clocks when Normal mode.
> > > +      *
> > > +      * DIVA [1:0] Division Ratio
> > > +      * 0 0 fosc
> > > +      * 0 1 fosc / 2
> > > +      * 1 0 fosc / 4
> > > +      * 1 1 fosc / 8
> > > +      *
> > > +      */
> > > +     u8 frc[ILI9341_FRC_LEN];
> > > +     /** @prc: TODO: need comments for this register */
> > > +     u8 prc;
> > > +     /** @dfc_1: B6h DISCTRL (Display Function Control) */
> > > +     /*               D/CX RDX WRX D17-8 D7  D6 D5 D4 D3   D2  D1  D0  HEX
> > > +      * Command       0    1   M   XX    1   0  1  1  0    1   1   0   B6h
> > > +      * 1st Parameter 1    1   M   XX    0   0  0  0  PTG[1:0] PT[1:0] 0A
> > > +      * 2nd Parameter 1    1   M   XX    REV GS SS SM ISC[3:0]         82
> > > +      * 3rd Parameter 1    1   M   XX    0   0  NL[5:0]                27
> > > +      * 4th Parameter 1    1   M   XX    0   0  PCDIV[5:0]             XX
> > > +      *
> > > +      * PTG [1:0]: Set the scan mode in non-display area.
> > > +      * PTG1 | PTG0 | Gate outputs in   | Source outputs in  | VCOM output
> > > +      *               non-display area  | non-display area   |
> > > +      * 1      0      Interval scan       Set with the PT[2:0] bits
> > > +      *
> > > +      * PT [1:0]: Determine source/VCOM output in a non-display area in the
> > > +      * partial display mode.
> > > +      * 1    0    AGND       AGND       AGND         AGND
> > > +      *
> > > +      * REV: Select whether the liquid crystal type is normally white type
> > > +      * or normally black type.
> > > +      * REV   Liquid crystal type
> > > +      * 0     Normally black
> > > +      * 1     Normally white
> > > +      *
> > > +      * SS: Select the shift direction of outputs from the source driver.
> > > +      * SS    Source Output Scan Direction
> > > +      * 0     S1 -> S720
> > > +      * 1     S720 -> S1
> > > +      *
> > > +      * GS: Sets the direction of scan by the gate driver in the range
> > > +      * determined by SCN [4:0] and NL [4:0]. The scan direction
> > > +      * determined by GS = 0 can be reversed by setting GS = 1.
> > > +      *
> > > +      * GS     Gate Output Scan Direction
> > > +      * 0      G1 -> G320
> > > +      * 1      G320 -> G1
> > > +      */
> > > +     u8 dfc_1[ILI9341_DFC_1_LEN];
> > > +      /** @power_1: Power Control 1 (C0h) */
> > > +      /* VRH [5:0]: Set the GVDD level, which is a reference level for the
> > > +      * VCOM level and the grayscale voltage level.
> > > +      *
> > > +      * VRH[5:0]    GVDD                     VRH[5:0]        GVDD
> > > +      * 0 0 0 0 0 0 Setting prohibited       1 0 0 0 0 0     4.45 V
> > > +      * 0 0 0 0 0 1 Setting prohibited       1 0 0 0 0 1     4.50 V
> > > +      * 0 0 0 0 1 0 Setting prohibited       1 0 0 0 1 0     4.55 V
> > > +      * 0 0 0 0 1 1 3.00 V                   1 0 0 0 1 1     4.60 V
> > > +      * 0 0 0 1 0 0 3.05 V                   1 0 0 1 0 0     4.65 V
> > > +      * 0 0 0 1 0 1 3.10 V                   1 0 0 1 0 1     4.70 V
> > > +      * 0 0 0 1 1 0 3.15 V                   1 0 0 1 1 0     4.75 V
> > > +      * 0 0 0 1 1 1 3.20 V                   1 0 0 1 1 1     4.80 V
> > > +      * 0 0 1 0 0 0 3.25 V                   1 0 1 0 0 0     4.85 V
> > > +      * 0 0 1 0 0 1 3.30 V                   1 0 1 0 0 1     4.90 V
> > > +      * 0 0 1 0 1 0 3.35 V                   1 0 1 0 1 0     4.95 V
> > > +      * 0 0 1 0 1 1 3.40 V                   1 0 1 0 1 1     5.00 V
> > > +      * 0 0 1 1 0 0 3.45 V                   1 0 1 1 0 0     5.05 V
> > > +      * 0 0 1 1 0 1 3.50 V                   1 0 1 1 0 1     5.10 V
> > > +      * 0 0 1 1 1 0 3.55 V                   1 0 1 1 1 0     5.15 V
> > > +      * 0 0 1 1 1 1 3.60 V                   1 0 1 1 1 1     5.20 V
> > > +      * 0 1 0 0 0 0 3.65 V                   1 1 0 0 0 0     5.25 V
> > > +      * 0 1 0 0 0 1 3.70 V                   1 1 0 0 0 1     5.30 V
> > > +      * 0 1 0 0 1 0 3.75 V                   1 1 0 0 1 0     5.35 V
> > > +      * 0 1 0 0 1 1 3.80 V                   1 1 0 0 1 1     5.40 V
> > > +      * 0 1 0 1 0 0 3.85 V                   1 1 0 1 0 0     5.45 V
> > > +      * 0 1 0 1 0 1 3.90 V                   1 1 0 1 0 1     5.50 V
> > > +      * 0 1 0 1 1 0 3.95 V                   1 1 0 1 1 0     5.55 V
> > > +      * 0 1 0 1 1 1 4.00 V                   1 1 0 1 1 1     5.60 V
> > > +      * 0 1 1 0 0 0 4.05 V                   1 1 1 0 0 0     5.65 V
> > > +      * 0 1 1 0 0 1 4.10 V                   1 1 1 0 0 1     5.70 V
> > > +      * 0 1 1 0 1 0 4.15 V                   1 1 1 0 1 0     5.75 V
> > > +      * 0 1 1 0 1 1 4.20 V                   1 1 1 0 1 1     5.80 V
> > > +      * 0 1 1 1 0 0 4.25 V                   1 1 1 1 0 0     5.85 V
> > > +      * 0 1 1 1 0 1 4.30 V                   1 1 1 1 0 1     5.90 V
> > > +      * 0 1 1 1 1 0 4.35 V                   1 1 1 1 1 0     5.95 V
> > > +      * 0 1 1 1 1 1 4.40 V                   1 1 1 1 1 1     6.00 V
> > > +      */
> > > +     u8 power_1;
> > > +     /** @power_2: Power Control 2 (C1h) */
> > > +     /*
> > > +      * BT [2:0]: Sets the factor used in the step-up circuits.
> > > +      * Select the optimal step-up factor for the operating voltage. To
> > > +      * reduce power consumption, set a smaller factor.
> > > +      *
> > > +      * BT[2:0]   AVDD     VGH      VGL
> > > +      * 0 0 0     VCI x 2  VCI x 7  VCI x 4
> > > +      * 0 0 1                       VCI x 3
> > > +      * 0 1 0              VCI x 6  VCI x 4
> > > +      * 0 1 1                       VCI x 3
> > > +      *
> > > +      */
> > > +     u8 power_2;
> > > +     /** @vcom_1: VCOM Control 1(C5h) */
> > > +     /*
> > > +      * VMH [6:0] : Set the VCOMH voltage
> > > +      *
> > > +      * VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH(V) VMH[6:0] VCOMH
> > > +      * 0000000  2.700    0100000  3.500    1000000  4.300    1100000  5.100
> > > +      * 0000001  2.725    0100001  3.525    1000001  4.325    1100001  5.125
> > > +      * 0000010  2.750    0100010  3.550    1000010  4.350    1100010  5.150
> > > +      * 0000011  2.775    0100011  3.575    1000011  4.375    1100011  5.175
> > > +      * 0000100  2.800    0100100  3.600    1000100  4.400    1100100  5.200
> > > +      * 0000101  2.825    0100101  3.625    1000101  4.425    1100101  5.225
> > > +      * 0000110  2.850    0100110  3.650    1000110  4.450    1100110  5.250
> > > +      * 0000111  2.875    0100111  3.675    1000111  4.475    1100111  5.275
> > > +      * 0001000  2.900    0101000  3.700    1001000  4.500    1101000  5.300
> > > +      * 0001001  2.925    0101001  3.725    1001001  4.525    1101001  5.325
> > > +      * 0001010  2.950    0101010  3.750    1001010  4.550    1101010  5.350
> > > +      * 0001011  2.975    0101011  3.775    1001011  4.575    1101011  5.375
> > > +      * 0001100  3.000    0101100  3.800    1001100  4.600    1101100  5.400
> > > +      * 0001101  3.025    0101101  3.825    1001101  4.625    1101101  5.425
> > > +      * 0001110  3.050    0101110  3.850    1001110  4.650    1101110  5.450
> > > +      * 0001111  3.075    0101111  3.875    1001111  4.675    1101111  5.475
> > > +      * 0010000  3.100    0110000  3.900    1010000  4.700    1110000  5.500
> > > +      * 0010001  3.125    0110001  3.925    1010001  4.725    1110001  5.525
> > > +      * 0010010  3.150    0110010  3.950    1010010  4.750    1110010  5.550
> > > +      * 0010011  3.175    0110011  3.975    1010011  4.775    1110011  5.575
> > > +      * 0010100  3.200    0110100  4.000    1010100  4.800    1110100  5.600
> > > +      * 0010101  3.225    0110101  4.025    1010101  4.825    1110101  5.625
> > > +      * 0010110  3.250    0110110  4.050    1010110  4.850    1110110  5.650
> > > +      * 0010111  3.275    0110111  4.075    1010111  4.875    1110111  5.675
> > > +      * 0011000  3.300    0111000  4.100    1011000  4.900    1111000  5.700
> > > +      * 0011001  3.325    0111001  4.125    1011001  4.925    1111001  5.725
> > > +      * 0011010  3.350    0111010  4.150    1011010  4.950    1111010  5.750
> > > +      * 0011011  3.375    0111011  4.175    1011011  4.975    1111011  5.775
> > > +      * 0011100  3.400    0111100  4.200    1011100  5.000    1111100  5.800
> > > +      * 0011101  3.425    0111101  4.225    1011101  5.025    1111101  5.825
> > > +      * 0011110  3.450    0111110  4.250    1011110  5.050    1111110  5.850
> > > +      * 0011111  3.475    0111111  4.275    1011111  5.075    1111111  5.875
> > > +      *
> > > +      * VML[6:0] : Set the VCOML voltage
> > > +      *
> > > +      * VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML(V) VML[6:0] VCOML
> > > +      * 0000000 -2.500 0100000 -1.700 1000000 -0.900 1100000 -0.100
> > > +      * 0000001 -2.475 0100001 -1.675 1000001 -0.875 1100001 -0.075
> > > +      * 0000010 -2.450 0100010 -1.650 1000010 -0.850 1100010 -0.050
> > > +      * 0000011 -2.425 0100011 -1.625 1000011 -0.825 1100011 -0.025
> > > +      * 0000100 -2.400 0100100 -1.600 1000100 -0.800 1100100 0
> > > +      * 0000101 -2.375 0100101 -1.575 1000101 -0.775 1100101 Reserved
> > > +      * 0000110 -2.350 0100110 -1.550 1000110 -0.750 1100110 Reserved
> > > +      * 0000111 -2.325 0100111 -1.525 1000111 -0.725 1100111 Reserved
> > > +      * 0001000 -2.300 0101000 -1.500 1001000 -0.700 1101000 Reserved
> > > +      * 0001001 -2.275 0101001 -1.475 1001001 -0.675 1101001 Reserved
> > > +      * 0001010 -2.250 0101010 -1.450 1001010 -0.650 1101010 Reserved
> > > +      * 0001011 -2.225 0101011 -1.425 1001011 -0.625 1101011 Reserved
> > > +      * 0001100 -2.200 0101100 -1.400 1001100 -0.600 1101100 Reserved
> > > +      * 0001101 -2.175 0101101 -1.375 1001101 -0.575 1101101 Reserved
> > > +      * 0001110 -2.150 0101110 -1.350 1001110 -0.550 1101110 Reserved
> > > +      * 0001111 -2.125 0101111 -1.325 1001111 -0.525 1101111 Reserved
> > > +      * 0010000 -2.100 0110000 -1.300 1010000 -0.500 1110000 Reserved
> > > +      * 0010001 -2.075 0110001 -1.275 1010001 -0.475 1110001 Reserved
> > > +      * 0010010 -2.050 0110010 -1.250 1010010 -0.450 1110010 Reserved
> > > +      * 0010011 -2.025 0110011 -1.225 1010011 -0.425 1110011 Reserved
> > > +      * 0010100 -2.000 0110100 -1.200 1010100 -0.400 1110100 Reserved
> > > +      * 0010101 -1.975 0110101 -1.175 1010101 -0.375 1110101 Reserved
> > > +      * 0010110 -1.950 0110110 -1.150 1010110 -0.350 1110110 Reserved
> > > +      * 0010111 -1.925 0110111 -1.125 1010111 -0.325 1110111 Reserved
> > > +      * 0011000 -1.900 0111000 -1.100 1011000 -0.300 1111000 Reserved
> > > +      * 0011001 -1.875 0111001 -1.075 1011001 -0.275 1111001 Reserved
> > > +      * 0011010 -1.850 0111010 -1.050 1011010 -0.250 1111010 Reserved
> > > +      * 0011011 -1.825 0111011 -1.025 1011011 -0.225 1111011 Reserved
> > > +      * 0011100 -1.800 0111100 -1.000 1011100 -0.200 1111100 Reserved
> > > +      * 0011101 -1.775 0111101 -0.975 1011101 -0.175 1111101 Reserved
> > > +      * 0011110 -1.750 0111110 -0.950 1011110 -0.150 1111110 Reserved
> > > +      * 0011111 -1.725 0111111 -0.925 1011111 -0.125 1111111 Reserved
> > > +      */
> > > +     u8 vcom_1[ILI9341_VCOM_1_LEN];
> > > +     /** @vcom_2: VCOM Control 2(C7h) */
> > > +     /*
> > > +      * C7h          VMCTRL1 (VCOM Control 1)
> > > +      *              D/CX RDX WRX D17-8 D7  D6  D5 D4 D3 D2 D1 D0 HEX
> > > +      * Command      0    1   M   XX    1   1   0  0  0  1  1  1  C7h
> > > +      * Parameter    1    1   M   XX    nVM VMF[6:0]              C0
> > > +      *
> > > +      * nVM: nVM equals to “0” after power on reset and VCOM offset
> > > +      * equals to program MTP value. When nVM set to “1”, setting
> > > +      * of VMF [6:0] becomes valid and VCOMH/VCOML can be adjusted.
> > > +      *
> > > +      * VMF [6:0]: Set the VCOM offset voltage.
> > > +      */
> > > +     u8 vcom_2;
> > > +     /** @address_mode: Memory Access Control (36h) */
> > > +     /*
> > > +      * 36h          MADCTL (Memory Access Control)
> > > +      *              D/CX RDX WRX D17-8 D7 D6 D5 D4 D3  D2 D1 D0 HEX
> > > +      * Command      0    1   M   XX    0  0  1  1  0   1  1  0  36h
> > > +      * Parameter    1    1   M   XX    MY MX MV ML BGR MH 0  0  00
> > > +      *
> > > +      * This command defines read/write scanning direction of frame memory.
> > > +      * This command makes no change on the other driver status.
> > > +      *
> > > +      * Bit  Name                     Description
> > > +      * MY   Row Address Order
> > > +      * MX   Column Address Order
> > > +      * MV   Row / Column Exchange    These 3 bits control MCU to memory
> > > +      *                               write/read direction.
> > > +      * ML   Vertical Refresh Order   LCD vertical refresh direction control.
> > > +      * BGR  RGB-BGR Order            Color selector switch control
> > > +      *                               (0=RGB color filter panel, 1=BGR
> > > +      *                               color filter panel)
> > > +      * MH   Horizontal Refresh ORDER LCD horizontal refreshing
> > > +      * direction control.
> > > +      *
> > > +      * Note: When BGR bit is changed, the new setting is active
> > > +      * immediately without update the content in Frame Memory again.
> > > +      *
> > > +      */
> > > +     u8 address_mode;
> > > +     /** @g3amma_en: TODO: need comments for this register */
> > > +     u8 g3amma_en;
> > > +     /** @rgb_interface: RGB Interface Signal Control (B0h) */
> > > +     /*
> > > +      * B0h          IFMODE (Interface Mode Control)
> > > +      *              D/CX RDX WRX D17-8 D7          D6     D5     D4 D3   D2   D1  D0  HEX
> > > +      * Command      0    1   M   XX    1           0      1      1  0    0    0   0   B0h
> > > +      * Parameter    1    1   M   XX    ByPass_MODE RCM[1] RCM[0] 0  VSPL HSPL DPL EPL 40
> > > +      *
> > > +      * Sets the operation status of the display interface. The setting
> > > +      * becomes effective as soon as the command is received.
> > > +      * EPL: DE polarity (“0”= High enable for RGB interface, “1”= Low
> > > +      * enable for RGB interface)
> > > +      *
> > > +      * DPL: DOTCLK polarity set (“0”= data fetched at the rising time,
> > > +      * “1”= data fetched at the falling time)
> > > +      *
> > > +      * HSPL: HSYNC polarity (“0”= Low level sync clock, “1”= High
> > > +      * level sync clock)
> > > +      *
> > > +      * VSPL: VSYNC polarity (“0”= Low level sync clock, “1”= High
> > > +      * level sync clock)
> > > +      *
> > > +      * RCM [1:0]: RGB interface selection (refer to the RGB interface
> > > +      * section).
> > > +      *
> > > +      * ByPass_MODE: Select display data path whether Memory or Direct to
> > > +      * Shift register when RGB Interface is used.
> > > +      *
> > > +      * ByPass_MODE  Display Data Path
> > > +      * 0            Direct to Shift Register (default)
> > > +      * 1            Memory
> > > +      */
> > > +     u8 rgb_interface;
> > > +     /** @dfc_2: refer to dfc_1 */
> > > +     u8 dfc_2[ILI9341_DFC_2_LEN];
> > > +     /** @column_addr: Column Address Set (2Ah) */
> > > +     /* This command is used to define area of frame memory where MCU can
> > > +      * access. This command makes no change on the
> > > +      * other driver status. The values of SC [15:0] and EC [15:0] are
> > > +      * referred when RAMWR command comes. Each value
> > > +      * represents one column line in the Frame Memory.
> > > +      */
> > > +     u8 column_addr[ILI9341_COLUMN_ADDR_LEN];
> > > +     /** @page_addr: Page Address Set (2Bh) */
> > > +     /* This command is used to define area of frame memory where MCU can
> > > +      * access. This command makes no change on the
> > > +      * other driver status. The values of SP [15:0] and EP [15:0] are
> > > +      * referred when RAMWR command comes. Each value
> > > +      * represents one Page line in the Frame Memory.
> > > +      */
> > > +     u8 page_addr[ILI9341_PAGE_ADDR_LEN];
> > > +     /** @interface: Interface Control (F6h) */
> > > +     /*
> > > +      * F6h          IFCTL (16bits Data Format Selection)
> > > +      *              D/CX RDX WRX D17-8 D7   D6   D5     D4     D3      D2     D1     D0      HEX
> > > +      * Command      0    1   M   XX    1    1    1      1      0       1      1      0       F6h
> > > +      * 1stParameter 1    1   M   XX    MY   MX   MV
> > > +      *                                 _EOR _EOR _EOR   0      BGR_EOR 0      0      WE MODE 01
> > > +      * 2ndParameter 1    1   M   XX    0    0    EPF[1] EPF[0] 0       0      MDT[1] MDT[0]  00
> > > +      * 3rdParameter 1    1   M   XX    0    0    ENDIAN 0      DM[1]   DM[0]  RM     RIM     00
> > > +      *
> > > +      */
> > > +     u8 interface[ILI9341_INTERFACE_LEN];
> > > +     /** @pixel_format: This command sets the pixel format for the RGB image data used by */
> > > +     /* the interface. DPI [2:0] is the pixel format select of RGB
> > > +      * interface and DBI [2:0] is the pixel format of MCU interface. If a
> > > +      * particular interface, either RGB interface or MCU interface, is
> > > +      * not used then the corresponding bits in the parameter are ignored.
> > > +      * The pixel format is shown in the table below.
> > > +      *
> > > +      * DPI[2:0]     RGB Interface Format    DBI[2:0] MCU Interface Format
> > > +      * 0 0 0        Reserved                0 0 0    Reserved
> > > +      * 0 0 1        Reserved                0 0 1    Reserved
> > > +      * 0 1 0        Reserved                0 1 0    Reserved
> > > +      * 0 1 1        Reserved                0 1 1    Reserved
> > > +      * 1 0 0        Reserved                1 0 0    Reserved
> > > +      * 1 0 1        16 bits / pixel         1 0 1    16 bits / pixel
> > > +      * 1 1 0        18 bits / pixel         1 1 0    18 bits / pixel
> > > +      * 1 1 1        Reserved                1 1 1    Reserved
> > > +      *
> > > +      */
> > > +     u8 pixel_format;
> > > +     /** @gamma_curve: This command is used to select the desired Gamma curve for the */
> > > +     /* current display. A maximum of 4 fixed gamma curves can
> > > +      * be selected. The curve is selected by setting the appropriate bit
> > > +      * in the parameter as described in the Table:
> > > +      *
> > > +      * GC [7:0]     Curve Selected
> > > +      * 01h          Gamma curve 1 (G2.2)
> > > +      * 02h          ---
> > > +      * 04h          ---
> > > +      * 08h          ---
> > > +      */
> > > +     u8 gamma_curve;
> > > +     /** @pgamma: Positive Gamma Correction (E0h) */
> > > +     /*
> > > +      * Set the gray scale voltage to adjust the gamma characteristics of
> > > +      * the TFT panel.
> > > +      */
> > > +     u8 pgamma[ILI9341_PGAMMA_LEN];
> > > +     /** @ngamma: Negative Gamma Correction (E1h) */
> > > +     /*
> > > +      * Set the gray scale voltage to adjust the gamma characteristics of
> > > +      * the TFT panel.
> > > +      */
> > > +     u8 ngamma[ILI9341_NGAMMA_LEN];
> > > +};
> > > +
> > > +struct ili9341 {
> > > +     struct device *dev;
> > > +     const struct ili9341_config *conf;
> > > +     struct drm_panel panel;
> > > +     struct gpio_desc *reset_gpio;
> > > +     struct gpio_desc *dc_gpio;
> > > +     u32 max_spi_speed;
> > > +     struct regulator *vcc;
> > > +};
> > > +
> > > +/*
> > > + * The Stm32f429-disco board has a panel ili9341 connected to ltdc controller
> > > + */
> > > +static const struct ili9341_config ili9341_stm32f429_disco_data = {
> > > +     .max_spi_speed = 10000000,
> > > +     .mode = {
> > > +             .clock = 6100,
> > > +             .hdisplay = 240,
> > > +             .hsync_start = 240 + 10,/* hfp 10 */
> > > +             .hsync_end = 240 + 10 + 10,/* hsync 10 */
> > > +             .htotal = 240 + 10 + 10 + 20,/* hbp 20 */
> > > +             .vdisplay = 320,
> > > +             .vsync_start = 320 + 4,/* vfp 4 */
> > > +             .vsync_end = 320 + 4 + 2,/* vsync 2 */
> > > +             .vtotal = 320 + 4 + 2 + 2,/* vbp 2 */
> > > +             .flags = 0,
> > > +             .width_mm = 65,
> > > +             .height_mm = 50,
> > > +             .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> > > +     },
> > > +     /* TODO: need comments for this register */
> > > +     .ca = {0xc3, 0x08, 0x50},
> > > +     /* TODO: need comments for this register */
> > > +     .power_b = {0x00, 0xc1, 0x30},
> > > +     /* TODO: need comments for this register */
> > > +     .power_seq = {0x64, 0x03, 0x12, 0x81},
> > > +     /* TODO: need comments for this register */
> > > +     .dtca = {0x85, 0x00, 0x78},
> > > +     /* TODO: need comments for this register */
> > > +     .power_a = {0x39, 0x2c, 0x00, 0x34, 0x02},
> > > +     /* TODO: need comments for this register */
> > > +     .prc = 0x20,
> > > +     /* TODO: need comments for this register */
> > > +     .dtcb = {0x00, 0x00},
> > > +     /* 0x00 fosc, 0x1b 70hz */
> > > +     .frc = {0x00, 0x1b},
> > > +     /* 0x0a Interval scan, AGND AGND AGND AGND
> > > +      * 0xa2 Normally white, G1 -> G320, S720 -> S1,
> > > +      *      Scan Cycle 5 frames,85ms
> > > +      */
> > > +     .dfc_1 = {0x0a, 0xa2},
> > > +     /* 0x10 3.65v */
> > > +     .power_1 = 0x10,
> > > +     /* 0x10 AVDD=vci*2, VGH=vci*7, VGL=-vci*4 */
> > > +     .power_2 = 0x10,
> > > +     /* 0x45 VCOMH 4.425v, 0x15 VCOML -1.975*/
> > > +     .vcom_1 = {0x45, 0x15},
> > > +     /* 0x90 offset voltage, VMH-48, VML-48 */
> > > +     .vcom_2 = 0x90,
> > > +     /* 0xc8 Row Address Order, Column Address Order
> > > +      *      BGR 1
> > > +      */
> > > +     .address_mode = 0xc8,
> > > +     .g3amma_en = 0x00,
> > > +     /* 0xc2
> > > +      * Display Data Path: Memory
> > > +      * RGB: DE mode
> > > +      * DOTCLK polarity set (data fetched at the falling time)
> > > +      */
> > > +     .rgb_interface = ILI9341_RGB_DISP_PATH_MEM |
> > > +                     ILI9341_RGB_DE_MODE |
> > > +                     ILI9341_RGB_DPL,
> > > +     /*
> > > +      * 0x0a
> > > +      * Gate outputs in non-display area: Interval scan
> > > +      * Determine source/VCOM output in a non-display area in the partial
> > > +      * display mode: AGND AGND AGND AGND
> > > +      *
> > > +      * 0xa7
> > > +      * Scan Cycle: 15 frames
> > > +      * fFLM = 60Hz: 255ms
> > > +      * Liquid crystal type: Normally white
> > > +      * Gate Output Scan Direction: G1 -> G320
> > > +      * Source Output Scan Direction: S720 -> S1
> > > +      *
> > > +      * 0x27
> > > +      * LCD Driver Line: 320 lines
> > > +      *
> > > +      * 0x04
> > > +      * PCDIV: 4
> > > +      */
> > > +     .dfc_2 = {0x0a, 0xa7, 0x27, 0x04},
> > > +     /* column address: 240 */
> > > +     .column_addr = {0x00, 0x00, (ILI9341_COLUMN_ADDR >> 4) & 0xff,
> > > +                             ILI9341_COLUMN_ADDR & 0xff},
> > > +     /* page address: 320 */
> > > +     .page_addr = {0x00, 0x00, (ILI9341_PAGE_ADDR >> 4) & 0xff,
> > > +                             ILI9341_PAGE_ADDR & 0xff},
> > > +     /* Memory write control: When the transfer number of data exceeds
> > > +      * (EC-SC+1)*(EP-SP+1), the column and page number will be
> > > +      * reset, and the exceeding data will be written into the following
> > > +      * column and page.
> > > +      * Display Operation Mode: RGB Interface Mode
> > > +      * Interface for RAM Access: RGB interface
> > > +      * 16- bit RGB interface (1 transfer/pixel)
> > > +      */
> > > +     .interface = {ILI9341_IF_WE_MODE, 0x00,
> > > +                     ILI9341_IF_DM_RGB | ILI9341_IF_RM_RGB},
> > > +     /* DPI: 16 bits / pixel */
> > > +     .pixel_format = ILI9341_PIXEL_DPI_16_BITS,
> > > +     /* Curve Selected: Gamma curve 1 (G2.2) */
> > > +     .gamma_curve = ILI9341_GAMMA_CURVE_1,
> > > +     .pgamma = {0x0f, 0x29, 0x24, 0x0c, 0x0e,
> > > +                     0x09, 0x4e, 0x78, 0x3c, 0x09,
> > > +                     0x13, 0x05, 0x17, 0x11, 0x00},
> > > +     .ngamma = {0x00, 0x16, 0x1b, 0x04, 0x11,
> > > +                     0x07, 0x31, 0x33, 0x42, 0x05,
> > > +                     0x0c, 0x0a, 0x28, 0x2f, 0x0f},
> > > +};
> > > +
> > > +static inline struct ili9341 *panel_to_ili9341(struct drm_panel *panel)
> > > +{
> > > +     return container_of(panel, struct ili9341, panel);
> > > +}
> > > +
> > > +static int ili9341_spi_transfer(struct spi_device *spi, u32 speed_hz,
> > > +                       u8 bpw, const void *buf, size_t len)
> > > +{
> > > +     size_t max_chunk = spi_max_transfer_size(spi);
> > > +     struct spi_transfer tr = {
> > > +             .bits_per_word = bpw,
> > > +             .speed_hz = speed_hz,
> > > +             .len = len,
> > > +     };
> > > +     struct spi_message m;
> > > +     size_t chunk;
> > > +     int ret;
> > > +
> > > +     spi_message_init_with_transfers(&m, &tr, 1);
> > > +
> > > +     while (len) {
> > > +             chunk = min(len, max_chunk);
> > > +
> > > +             tr.tx_buf = buf;
> > > +             tr.len = chunk;
> > > +             buf += chunk;
> > > +             len -= chunk;
> > > +
> > > +             ret = spi_sync(spi, &m);
> > > +             if (ret) {
> > > +                     dev_err(&spi->dev, "spi_sync error: %d\n", ret);
> > > +                     return ret;
> > > +             }
> > > +     }
> > > +     return 0;
> > > +}
> > > +
> > > +static int _ili9341_command(struct ili9341 *ili, u8 cmd, const void *data,
> > > +                                 size_t count)
> > > +{
> > > +     struct spi_device *spi = to_spi_device(ili->dev);
> > > +     int ret = 0;
> > > +
> > > +     gpiod_set_value_cansleep(ili->dc_gpio, 0);
> > > +
> > > +     ret = ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
> > > +                                     (const void *)&cmd, 1);
> > > +     if (ret || data == NULL || count == 0) {
> > > +             return ret;
> > > +     }
> > > +
> > > +     gpiod_set_value_cansleep(ili->dc_gpio, 1);
> > > +
> > > +     return ili9341_spi_transfer(spi, ili->max_spi_speed, 8,
> > > +             data, count);
> > > +}
> > > +
> > > +static int ili9341_dpi_init(struct ili9341 *ili)
> > > +{
> > > +     int ret;
> > > +     ret = _ili9341_command(ili, 0xca,
> > > +                     ili->conf->ca,
> > > +                     ILI9341_CA_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_POWERB,
> > > +                     ili->conf->power_b,
> > > +                     ILI9341_POWER_B_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_POWER_SEQ,
> > > +                     ili->conf->power_seq,
> > > +                     ILI9341_POWER_SEQ_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_DTCA,
> > > +                     ili->conf->dtca,
> > > +                     ILI9341_DTCA_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_POWERA,
> > > +                     ili->conf->power_a,
> > > +                     ILI9341_POWER_A_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_PRC,
> > > +                     &ili->conf->prc,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_DTCB,
> > > +                     ili->conf->dtcb,
> > > +                     ILI9341_DTCB_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_FRC,
> > > +                     ili->conf->frc,
> > > +                     ILI9341_FRC_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_DFC,
> > > +                     ili->conf->dfc_1,
> > > +                     ILI9341_DFC_1_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_POWER1,
> > > +                     &ili->conf->power_1,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_POWER2,
> > > +                     &ili->conf->power_2,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_VCOM1,
> > > +                     ili->conf->vcom_1,
> > > +                     ILI9341_VCOM_1_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_VCOM2,
> > > +                     &ili->conf->vcom_2,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, MIPI_DCS_SET_ADDRESS_MODE,
> > > +                     &ili->conf->address_mode,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_3GAMMA_EN,
> > > +                     &ili->conf->g3amma_en,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_RGB_INTERFACE,
> > > +                     &ili->conf->rgb_interface,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_DFC,
> > > +                     ili->conf->dfc_2,
> > > +                     ILI9341_DFC_2_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, MIPI_DCS_SET_COLUMN_ADDRESS,
> > > +                     ili->conf->column_addr,
> > > +                     ILI9341_COLUMN_ADDR_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, MIPI_DCS_SET_PAGE_ADDRESS,
> > > +                     ili->conf->page_addr,
> > > +                     ILI9341_PAGE_ADDR_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_INTERFACE,
> > > +                     ili->conf->interface,
> > > +                     ILI9341_INTERFACE_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, MIPI_DCS_SET_PIXEL_FORMAT,
> > > +                     &ili->conf->pixel_format,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     msleep(200);
> > > +     ret = _ili9341_command(ili, MIPI_DCS_SET_GAMMA_CURVE,
> > > +                     &ili->conf->gamma_curve,
> > > +                     1);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_PGAMMA,
> > > +                     ili->conf->pgamma,
> > > +                     ILI9341_PGAMMA_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = _ili9341_command(ili, ILI9341_NGAMMA,
> > > +                     ili->conf->ngamma,
> > > +                     ILI9341_NGAMMA_LEN);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = ili9341_command(ili, MIPI_DCS_EXIT_SLEEP_MODE);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     msleep(200);
> > > +     ret = ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = ili9341_command(ili, MIPI_DCS_WRITE_MEMORY_START);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     dev_info(ili->dev, "initialized display rgb interface\n");
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int ili9341_dpi_power_on(struct ili9341 *ili)
> > > +{
> > > +     int ret = 0;
> > > +
> > > +     /* Assert RESET */
> > > +     gpiod_set_value(ili->reset_gpio, 1);
> > > +
> > > +     /* Enable power */
> > > +     if (!IS_ERR(ili->vcc)) {
> > > +             ret = regulator_enable(ili->vcc);
> > > +             if (ret < 0) {
> > > +                     dev_err(ili->dev, "unable to enable vcc\n");
> > > +                     return ret;
> > > +             }
> > > +     }
> > > +     msleep(20);
> > > +
> > > +     /* De-assert RESET */
> > > +     gpiod_set_value(ili->reset_gpio, 0);
> > > +     msleep(10);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int ili9341_dpi_power_off(struct ili9341 *ili)
> > > +{
> > > +     /* Assert RESET */
> > > +     gpiod_set_value(ili->reset_gpio, 1);
> > > +
> > > +     /* Disable power */
> > > +     if (!IS_ERR(ili->vcc))
> > > +             return regulator_disable(ili->vcc);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int ili9341_dpi_disable(struct drm_panel *panel)
> > > +{
> > > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > > +
> > > +     ili9341_command(ili, MIPI_DCS_SET_DISPLAY_OFF);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int ili9341_dpi_unprepare(struct drm_panel *panel)
> > > +{
> > > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > > +
> > > +     return ili9341_dpi_power_off(ili);
> > > +}
> > > +
> > > +static int ili9341_dpi_prepare(struct drm_panel *panel)
> > > +{
> > > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > > +     int ret;
> > > +
> > > +     ret = ili9341_dpi_power_on(ili);
> > > +     if (ret < 0)
> > > +             return ret;
> > > +
> > > +     ret = ili9341_dpi_init(ili);
> > > +     if (ret < 0)
> > > +             ili9341_dpi_unprepare(panel);
> > > +
> > > +     return ret;
> > > +}
> > > +
> > > +static int ili9341_dpi_enable(struct drm_panel *panel)
> > > +{
> > > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > > +
> > > +     ili9341_command(ili, MIPI_DCS_SET_DISPLAY_ON);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int ili9341_dpi_get_modes(struct drm_panel *panel,
> > > +                             struct drm_connector *connector)
> > > +{
> > > +     struct ili9341 *ili = panel_to_ili9341(panel);
> > > +     struct drm_device *drm = connector->dev;
> > > +     struct drm_display_mode *mode;
> > > +     struct drm_display_info *info;
> > > +
> > > +     info = &connector->display_info;
> > > +     info->width_mm = ili->conf->mode.width_mm;
> > > +     info->height_mm = ili->conf->mode.height_mm;
> > > +
> > > +     if (ili->conf->rgb_interface & ILI9341_RGB_DPL)
> > > +             info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
> > > +     else
> > > +             info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
> > > +
> > > +     if (ili->conf->rgb_interface & ILI9341_RGB_EPL)
> > > +             info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
> > > +     else
> > > +             info->bus_flags |= DRM_BUS_FLAG_DE_HIGH;
> > > +
> > > +     mode = drm_mode_duplicate(drm, &ili->conf->mode);
> > > +     if (!mode) {
> > > +             DRM_ERROR("bad mode or failed to add mode\n");
> > > +             return -EINVAL;
> > > +     }
> > > +     drm_mode_set_name(mode);
> > > +
> > > +     /* Set up the polarity */
> > > +     if (ili->conf->rgb_interface & ILI9341_RGB_HSPL)
> > > +             mode->flags |= DRM_MODE_FLAG_PHSYNC;
> > > +     else
> > > +             mode->flags |= DRM_MODE_FLAG_NHSYNC;
> > > +
> > > +     if (ili->conf->rgb_interface & ILI9341_RGB_VSPL)
> > > +             mode->flags |= DRM_MODE_FLAG_PVSYNC;
> > > +     else
> > > +             mode->flags |= DRM_MODE_FLAG_NVSYNC;
> > > +
> > > +     drm_mode_probed_add(connector, mode);
> > > +
> > > +     return 1; /* Number of modes */
> > > +}
> > > +
> > > +static const struct drm_panel_funcs ili9341_dpi_funcs = {
> > > +     .disable = ili9341_dpi_disable,
> > > +     .unprepare = ili9341_dpi_unprepare,
> > > +     .prepare = ili9341_dpi_prepare,
> > > +     .enable = ili9341_dpi_enable,
> > > +     .get_modes = ili9341_dpi_get_modes,
> > > +};
> > > +
> > > +static int ili9341_dpi_probe(struct spi_device *spi)
> > > +{
> > > +     int ret;
> > > +     struct device *dev = &spi->dev;
> > > +     struct ili9341 *ili;
> > > +
> > > +     ili = devm_kzalloc(dev, sizeof(struct ili9341), GFP_KERNEL);
> > > +     if (!ili)
> > > +             return -ENOMEM;
> > > +
> > > +     spi_set_drvdata(spi, ili);
> > > +
> > > +     ili->dev = dev;
> > > +     /*
> > > +      * Every new incarnation of this display must have a unique
> > > +      * data entry for the system in this driver.
> > > +      */
> > > +     ili->conf = of_device_get_match_data(dev);
> > > +     if (!ili->conf) {
> > > +             dev_err(dev, "missing device configuration\n");
> > > +             return -ENODEV;
> > > +     }
> > > +
> > > +     ili->vcc = devm_regulator_get_optional(dev, "vcc");
> > > +     if (IS_ERR(ili->vcc))
> > > +             dev_err(dev, "get optional vcc failed\n");
> > > +
> > > +     ili->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> > > +             GPIOD_OUT_HIGH);
> > > +     if (IS_ERR(ili->reset_gpio)) {
> > > +             dev_err(dev, "failed to get RESET GPIO\n");
> > > +             return PTR_ERR(ili->reset_gpio);
> > > +     }
> > > +
> > > +     ili->dc_gpio = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
> > > +     if (IS_ERR(ili->dc_gpio)) {
> > > +             dev_err(dev, "failed to get DC GPIO\n");
> > > +             return PTR_ERR(ili->dc_gpio);
> > > +     }
> > > +
> > > +     spi->bits_per_word = 8;
> > > +     ret = spi_setup(spi);
> > > +     if (ret < 0) {
> > > +             dev_err(dev, "spi setup failed.\n");
> > > +             return ret;
> > > +     }
> > > +
> > > +     ili->max_spi_speed = ili->conf->max_spi_speed;
> > > +
> > > +     drm_panel_init(&ili->panel, dev, &ili9341_dpi_funcs,
> > > +                    DRM_MODE_CONNECTOR_DPI);
> > > +
> > > +     drm_panel_add(&ili->panel);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +
> > > +
> > > +static void ili9341_dbi_enable(struct drm_simple_display_pipe *pipe,
> > > +                          struct drm_crtc_state *crtc_state,
> > > +                          struct drm_plane_state *plane_state)
> > > +{
> > > +     struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
> > > +     struct mipi_dbi *dbi = &dbidev->dbi;
> > > +     u8 addr_mode;
> > > +     int ret, idx;
> > > +
> > > +     if (!drm_dev_enter(pipe->crtc.dev, &idx))
> > > +             return;
> > > +
> > > +     DRM_DEBUG_KMS("\n");
> > > +
> > > +     ret = mipi_dbi_poweron_conditional_reset(dbidev);
> > > +     if (ret < 0)
> > > +             goto out_exit;
> > > +     if (ret == 1)
> > > +             goto out_enable;
> > > +
> > > +     mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
> > > +
> > > +     mipi_dbi_command(dbi, ILI9341_POWERB, 0x00, 0xc1, 0x30);
> > > +     mipi_dbi_command(dbi, ILI9341_POWER_SEQ, 0x64, 0x03, 0x12, 0x81);
> > > +     mipi_dbi_command(dbi, ILI9341_DTCA, 0x85, 0x00, 0x78);
> > > +     mipi_dbi_command(dbi, ILI9341_POWERA, 0x39, 0x2c, 0x00, 0x34, 0x02);
> > > +     mipi_dbi_command(dbi, ILI9341_PRC, ILI9341_DBI_PRC_NORMAL);
> > > +     mipi_dbi_command(dbi, ILI9341_DTCB, 0x00, 0x00);
> > > +
> > > +     /* Power Control */
> > > +     mipi_dbi_command(dbi, ILI9341_POWER1, ILI9341_DBI_VCOMH_4P6V);
> > > +     mipi_dbi_command(dbi, ILI9341_POWER2, ILI9341_DBI_PWR_2_DEFAULT);
> > > +     /* VCOM */
> > > +     mipi_dbi_command(dbi, ILI9341_VCOM1, ILI9341_DBI_VCOM_1_VMH_4P25V,
> > > +                                             ILI9341_DBI_VCOM_1_VML_1P5V);
> > > +     mipi_dbi_command(dbi, ILI9341_VCOM2, ILI9341_DBI_VCOM_2_DEC_58);
> > > +
> > > +     /* Memory Access Control */
> > > +     mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT,
> > > +                             MIPI_DCS_PIXEL_FMT_16BIT);
> > > +
> > > +     /* Frame Rate */
> > > +     mipi_dbi_command(dbi, ILI9341_FRC, ILI9341_DBI_FRC_DIVA & 0x03,
> > > +                                             ILI9341_DBI_FRC_RTNA & 0x1f);
> > > +
> > > +     /* Gamma */
> > > +     mipi_dbi_command(dbi, ILI9341_3GAMMA_EN, 0x00);
> > > +     mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, ILI9341_GAMMA_CURVE_1);
> > > +     mipi_dbi_command(dbi, ILI9341_PGAMMA,
> > > +                      0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
> > > +                      0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
> > > +     mipi_dbi_command(dbi, ILI9341_NGAMMA,
> > > +                      0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
> > > +                      0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
> > > +
> > > +     /* DDRAM */
> > > +     mipi_dbi_command(dbi, ILI9341_ETMOD, ILI9341_DBI_EMS_GAS |
> > > +                                             ILI9341_DBI_EMS_DTS |
> > > +                                             ILI9341_DBI_EMS_GON);
> > > +
> > > +     /* Display */
> > > +     mipi_dbi_command(dbi, ILI9341_DFC, 0x08, 0x82, 0x27, 0x00);
> > > +     mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
> > > +     msleep(100);
> > > +
> > > +     mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
> > > +     msleep(100);
> > > +
> > > +out_enable:
> > > +     switch (dbidev->rotation) {
> > > +     default:
> > > +             addr_mode = ILI9341_MADCTL_MX;
> > > +             break;
> > > +     case 90:
> > > +             addr_mode = ILI9341_MADCTL_MV;
> > > +             break;
> > > +     case 180:
> > > +             addr_mode = ILI9341_MADCTL_MY;
> > > +             break;
> > > +     case 270:
> > > +             addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
> > > +                         ILI9341_MADCTL_MX;
> > > +             break;
> > > +     }
> > > +     addr_mode |= ILI9341_MADCTL_BGR;
> > > +     mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
> > > +     mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
> > > +     DRM_DEBUG_KMS("initialized display serial interface\n");
> > > +out_exit:
> > > +     drm_dev_exit(idx);
> > > +}
> > > +
> > > +static const struct drm_simple_display_pipe_funcs ili9341_dbi_funcs = {
> > > +     .enable = ili9341_dbi_enable,
> > > +     .disable = mipi_dbi_pipe_disable,
> > > +     .update = mipi_dbi_pipe_update,
> > > +     .prepare_fb = drm_gem_simple_display_pipe_prepare_fb,
> > > +};
> > > +
> > > +static const struct drm_display_mode ili9341_dbi_mode = {
> > > +     DRM_SIMPLE_MODE(240, 320, 37, 49),
> > > +};
> > > +
> > > +DEFINE_DRM_GEM_CMA_FOPS(ili9341_dbi_fops);
> > > +
> > > +static struct drm_driver ili9341_dbi_driver = {
> > > +     .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> > > +     .fops                   = &ili9341_dbi_fops,
> > > +     DRM_GEM_CMA_DRIVER_OPS_VMAP,
> > > +     .debugfs_init           = mipi_dbi_debugfs_init,
> > > +     .name                   = "ili9341",
> > > +     .desc                   = "Ilitek ILI9341",
> > > +     .date                   = "20180514",
> > > +     .major                  = 1,
> > > +     .minor                  = 0,
> > > +};
> > > +static int ili9341_dbi_probe(struct spi_device *spi)
> > > +{
> > > +     struct mipi_dbi_dev *dbidev;
> > > +     struct drm_device *drm;
> > > +     struct mipi_dbi *dbi;
> > > +     struct gpio_desc *dc;
> > > +     struct device *dev = &spi->dev;
> > > +     u32 rotation = 0;
> > > +     int ret;
> > > +
> > > +     dbidev = devm_drm_dev_alloc(dev, &ili9341_dbi_driver,
> > > +                                 struct mipi_dbi_dev, drm);
> > > +     if (IS_ERR(dbidev))
> > > +             return PTR_ERR(dbidev);
> > > +
> > > +     dbi = &dbidev->dbi;
> > > +     drm = &dbidev->drm;
> > > +
> > > +     drm_mode_config_init(drm);
> > > +
> > > +     dbi->reset = devm_gpiod_get_optional(dev, "reset",
> > > +                                     GPIOD_OUT_HIGH);
> > > +     if (IS_ERR(dbi->reset)) {
> > > +             DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
> > > +             return PTR_ERR(dbi->reset);
> > > +     }
> > > +
> > > +     dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
> > > +     if (IS_ERR(dc)) {
> > > +             DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
> > > +             return PTR_ERR(dc);
> > > +     }
> > > +
> > > +     dbidev->regulator = devm_regulator_get_optional(dev, "vcc");
> > > +     if (IS_ERR(dbidev->regulator))
> > > +             dev_err(dev, "get optional vcc failed\n");
> > > +
> > > +     dbidev->backlight = devm_of_find_backlight(dev);
> > > +     if (IS_ERR(dbidev->backlight))
> > > +             return PTR_ERR(dbidev->backlight);
> > > +
> > > +     device_property_read_u32(dev, "rotation", &rotation);
> > > +
> > > +     ret = mipi_dbi_spi_init(spi, dbi, dc);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = mipi_dbi_dev_init(dbidev, &ili9341_dbi_funcs,
> > > +                                     &ili9341_dbi_mode, rotation);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     drm_mode_config_reset(drm);
> > > +
> > > +     ret = drm_dev_register(drm, 0);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     spi_set_drvdata(spi, drm);
> > > +
> > > +     drm_fbdev_generic_setup(drm, 0);
> > > +
> > > +     return 0;
> > > +}
> > > +static int ili9341_probe(struct spi_device *spi)
> > > +{
> > > +     const struct spi_device_id *id = spi_get_device_id(spi);
> > > +
> > > +     if (!strcmp(id->name, "sf-tc240t-9370-t"))
> > > +             return ili9341_dpi_probe(spi);
> > > +     else if (!strcmp(id->name, "yx240qv29"))
> > > +             return ili9341_dbi_probe(spi);
> > > +
> > > +     return -1;
> > > +}
> > > +
> > > +static int ili9341_remove(struct spi_device *spi)
> > > +{
> > > +     const struct spi_device_id *id = spi_get_device_id(spi);
> > > +     struct ili9341 *ili = spi_get_drvdata(spi);
> > > +     struct drm_device *drm = spi_get_drvdata(spi);
> > > +
> > > +     if (!strcmp(id->name, "sf-tc240t-9370-t")) {
> > > +             ili9341_dpi_power_off(ili);
> > > +             drm_panel_remove(&ili->panel);
> > > +     } else if (!strcmp(id->name, "yx240qv29")) {
> > > +             drm_dev_unplug(drm);
> > > +             drm_atomic_helper_shutdown(drm);
> > > +     }
> > > +     return 0;
> > > +}
> > > +
> > > +static void ili9341_shutdown(struct spi_device *spi)
> > > +{
> > > +     const struct spi_device_id *id = spi_get_device_id(spi);
> > > +
> > > +     if (!strcmp(id->name, "yx240qv29"))
> > > +             drm_atomic_helper_shutdown(spi_get_drvdata(spi));
> > > +}
> > > +
> > > +static const struct of_device_id ili9341_of_match[] = {
> > > +     {
> > > +             .compatible = "st,sf-tc240t-9370-t",
> > > +             .data = &ili9341_stm32f429_disco_data,
> > > +     },
> > > +     {
> > > +             /* porting from tiny/ili9341.c
> > > +              * for original mipi dbi compitable
> > > +              */
> > > +             .compatible = "adafruit,yx240qv29",
> > > +             .data = NULL,
> > > +     },
> > > +};
> > > +MODULE_DEVICE_TABLE(of, ili9341_of_match);
> > > +
> > > +static const struct spi_device_id ili9341_id[] = {
> > > +     { "yx240qv29", 0 },
> > > +     { "sf-tc240t-9370-t", 0 },
> > > +     { }
> > > +};
> > > +MODULE_DEVICE_TABLE(spi, ili9341_id);
> > > +
> > > +static struct spi_driver ili9341_driver = {
> > > +     .probe = ili9341_probe,
> > > +     .remove = ili9341_remove,
> > > +     .shutdown = ili9341_shutdown,
> > > +     .id_table = ili9341_id,
> > > +     .driver = {
> > > +             .name = "panel-ilitek-ili9341",
> > > +             .of_match_table = ili9341_of_match,
> > > +     },
> > > +};
> > > +module_spi_driver(ili9341_driver);
> > > +
> > > +MODULE_AUTHOR("Dillon Min <dillon.minfei@gmail.com>");
> > > +MODULE_DESCRIPTION("ILI9341 LCD panel driver");
> > > +MODULE_LICENSE("GPL v2");
> > >

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-05-31 14:58         ` Patrice CHOTARD
@ 2021-06-01  3:28           ` Dillon Min
  2021-06-01  8:00             ` Patrice CHOTARD
  0 siblings, 1 reply; 20+ messages in thread
From: Dillon Min @ 2021-06-01  3:28 UTC (permalink / raw)
  To: Patrice CHOTARD
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

Hi Patrice

On Mon, May 31, 2021 at 10:58 PM Patrice CHOTARD
<patrice.chotard@foss.st.com> wrote:
>
> Hi Dillon
>
> On 5/31/21 4:29 PM, Dillon Min wrote:
> > Hi Patrice
> >
> > On Mon, May 31, 2021 at 9:51 PM Patrice CHOTARD
> > <patrice.chotard@foss.st.com> wrote:
> >>
> >>
> >>
> >> On 5/31/21 3:38 PM, Dillon Min wrote:
> >>> Hi Patrice
> >>>
> >>> Thanks for your time to test my patch.
> >>>
> >>> On Mon, May 31, 2021 at 9:20 PM Patrice CHOTARD
> >>> <patrice.chotard@foss.st.com> wrote:
> >>>>
> >>>> Hi Dillon
> >>>>
> >>>>
> >>>>
> >>>> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> >>>>> From: Dillon Min <dillon.minfei@gmail.com>
> >>>>>
> >>>>> This seriese fix three i2c/clk bug for stm32 f4/f7
> >>>>> - kernel runing in sdram, i2c driver get data timeout
> >>>>> - ltdc clk turn off after kernel console active
> >>>>> - kernel hang in set ltdc clock rate
> >>>>>
> >>>>> clk bug found on stm32f429/f469-disco board
> >>>>>
> >>>>> Hi Patrice:
> >>>>> below is the guide to verify the patch:
> >>>>>
> >>>>> setup test env with following files(link at below 'files link'):
> >>>>> [1] u-boot-dtb.bin
> >>>>> [2] rootfs zip file (used in kernel initramfs)
> >>>>> [3] u-boot's mkimage to create itb file
> >>>>> [4] kernel config file
> >>>>> [5] my itb with-or-without i2c patch
> >>>>>
> >>>>> This patch based on kernel commit:
> >>>>> 88b06399c9c766c283e070b022b5ceafa4f63f19
> >>>>>
> >>>>> Note:
> >>>>> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
> >>>>> get accepted. it's used to setup touch screen calibration, then test i2c.
> >>>>>
> >>>>> create itb file(please correct path of 'data'):
> >>>>> ./mkimage -f stm32.its stm32.itb
> >>>>>
> >>>>> HW setup:
> >>>>> console:
> >>>>>        PA9, PA10
> >>>>>        usart0
> >>>>>        serial@40011000
> >>>>>        115200 8n1
> >>>>>
> >>>>> -- flash u-boot.bin to stm32f429-disco on PC
> >>>>> $ sudo openocd -f board/stm32f429discovery.cfg -c \
> >>>>>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
> >>>>>
> >>>>> -- setup kernel load bootargs at u-boot
> >>>>> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
> >>>>>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
> >>>>> U-Boot > loady;bootm
> >>>>> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
> >>>>>
> >>>>
> >>>>
> >>>> Thanks for these informations
> >>>> I was able to load and boot DTB and uImage directly in SDRAM as you suggested,
> >>>> i saw Linux logo and kernel log on the STM32F429-disco display,
> >>>> but i can't reach the login.
> >>>>
> >>>> The last kernel log i got is :
> >>>>
> >>>> Starting kernel ...
> >>>>
> >>>> [    0.000000] Booting Linux on physical CPU 0x0
> >>>> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
> >>>> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
> >>>> [    0.000000] CPU: unknown data cache, unknown instruction cache
> >>>> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
> >>>> [    0.000000] Zone ranges:
> >>>> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
> >>>> [    0.000000] Movable zone start for each node
> >>>> [    0.000000] Early memory node ranges
> >>>>
> >>>> [...]
> >>>>
> >>>> [    2.637564] printk: console [ttySTM0] enabled
> >>>> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
> >>>> [    2.758986] spi_stm32 40015000.spi: driver initialized
> >>>> [    2.795733] i2c /dev entries driver
> >>>> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
> >>>> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
> >>>> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
> >>>> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
> >>>> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
> >>>> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
> >>>> [    3.765208] Console: switching to colour frame buffer device 30x40
> >>>> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
> >>>> [    4.212737] Freeing unused kernel memory: 324K
> >>>> [    4.287300] This architecture does not have kernel memory protection.
> >>>> [    4.401202] Run /linuxrc as init process
> >>>> [    4.478622]   with arguments:
> >>>> [    4.555069]     /linuxrc
> >>>> [    4.595406]   with environment:
> >>>> [    4.672213]     HOME=/
> >>>> [    4.712511]     TERM=linux
> >>>> [  206.785289] random: crng init done
> >>>
> >>> I guess you didn't add the rootfs to uImage I sent you.
> >>
> >> I do use your rootfs
> >>
> >>> Could you post all the logs from u-boot startup to kernel log end.
> >>
> >>
> >> U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)
> >>
> >> DRAM:  8 MiB
> >> Flash: 2 MiB
> >> Loading Environment from Flash... OK
> >> In:    serial@40011000
> >> Out:   serial@40011000
> >> Err:   serial@40011000
> >> Hit any key to stop autoboot:  0
> >> U-Boot >    setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/lin'
> >
> > It seems bootargs are broken here.
> > should be setenv bootargs 'console=tty0 console=ttySTM0,115200
> > root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
>
> It's just a copy/paste issue from my minicom window to my mailer,
> but the bootargs is correct ;-)
>
> See a correct U-boot/kernel log in attached.

Yes, your log is ok.
I tried to follow your way(dtb + uImage) to figure out
why your kernel was hanging there, but no luck.

You can find my log from [1] .
(since my uImage is bigger than yours, i change the
loadaddr to 0x90300000, 0x90306000)

but there are some points we can check:
-  kernel config, you can find my config in [2],
    could you share yours to me as well, i can based on
    your configs to test.
-  uImage size (yours 1593664 bytes is quite smaller than mine, 2072864 bytes
    the difference based on kernel config and rootfs size)
-  cross tool chain (upload my toolchain to google drive [3])
-  could you add initcall_debug to your bootargs, to see more log
    at kernel startup

[1] kernel log based on dtb + uImage
https://drive.google.com/file/d/1wnA5b3B_6MIb4PWZXn-3DlBbxpi41uSA/view?usp=sharing

[2] kernel config
https://drive.google.com/file/d/1oOJt3NRYor3-Uzjpzrujv3uvWguxYQQp/view?usp=sharing

[3] arm-none-eabi- toolchain
https://drive.google.com/file/d/1Aq0sF2Gi4y4qaDPnM2S0xCOowFSLZYJm/view?usp=sharing

Best Regards
Dillon

>
>
> >
> >> U-Boot >
> >> U-Boot >
> >> U-Boot > setenv loadaddr 0x90400000
> >> U-Boot > loady
> >> ## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...
> >> CxyzModem - CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 7 retries
> >> ## Total Size      = 0x00004cad = 19629 Bytes
> >> U-Boot > setenv loadaddr 0x90406000
> >> U-Boot > loady
> >> ## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...
> >> C- CRC mode, 12453(SOH)/0(STX)/0(CAN) packets, 4 retries
> >> ## Total Size      = 0x00185140 = 1593664 Bytes
> >> U-Boot > bootm 0x90406000 - 0x90400000
> >> ## Booting kernel from Legacy Image at 90406000 ...
> >>    Image Name:   Linux-5.13.0-rc1-00082-g9dbbd5cb
> >>    Image Type:   ARM Linux Kernel Image (uncompressed)
> >>    Data Size:    1593600 Bytes = 1.5 MiB
> >>    Load Address: 90008000
> >>    Entry Point:  90008000
> >>    Verifying Checksum ... OK
> >> ## Flattened Device Tree blob at 90400000
> >>    Booting using the fdt blob at 0x90400000
> >>    Loading Kernel Image
> >>    Loading Device Tree to 905b9000, end 905c0cac ... OK
> >>
> >> Starting kernel ...
> >>
> >> [    0.000000] Booting Linux on physical CPU 0x0
> >> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
> >> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
> >> [    0.000000] CPU: unknown data cache, unknown instruction cache
> >> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
> >> [    0.000000] Zone ranges:
> >> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
> >> [    0.000000] Movable zone start for each node
> >> [    0.000000] Early memory node ranges
> >> [    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
> >> [    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
> >> [    0.000000] On node 0 totalpages: 2048
> >> [    0.000000]   Normal zone: 16 pages used for memmap
> >> [    0.000000]   Normal zone: 0 pages reserved
> >> [    0.000000]   Normal zone: 2048 pages, LIFO batch:0
> >> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
> >> [    0.000000] pcpu-alloc: [0] 0
> >> [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
> >> [    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdin2
> >
> > ditto
>
> same explanation as above, the command line displayed is truncated, but it is the one expected.
>
>
> >
> >> [    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> >> [    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> >> [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
> >> [    0.000000] Memory: 5264K/8192K available (1372K kernel code, 302K rwdata, 516K rodata,)
> >> [    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
> >> [    0.000000] rcu: Preemptible hierarchical RCU implementation.
> >> [    0.000000] rcu:     RCU event tracing is enabled.
> >> [    0.000000]  Trampoline variant of Tasks RCU enabled.
> >> [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
> >> [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
> >> [    0.000000] /soc/interrupt-controller@40013c00: bank0
> >> [    0.000000] random: get_random_bytes called from start_kernel+0x203/0x370 with crng_ini0
> >> [    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idls
> >> [    0.000000] ARM System timer initialized as clocksource
> >> [    0.000026] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
> >> [    0.000665] timer@40000c00: STM32 sched_clock registered
> >> [    0.001275] Switching to timer-based delay loop, resolution 11ns
> >> [    0.001712] timer@40000c00: STM32 delay timer registered
> >> [    0.002253] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_is
> >> [    0.003076] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
> >> [    0.014135] Console: colour dummy device 80x30
> >> [    0.062375] printk: console [tty0] enabled
> >> [    0.063843] Calibrating delay loop (skipped), value calculated using timer frequency.. )
> >> [    0.066453] pid_max: default: 4096 minimum: 301
> >> [    0.071393] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> >> [    0.073734] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
> >> [    0.104759] rcu: Hierarchical SRCU implementation.
> >> [    0.111552] devtmpfs: initialized
> >> [    0.339332] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:s
> >> [    0.341835] pinctrl core: initialized pinctrl subsystem
> >> [    0.658423] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
> >> [    0.680505] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
> >> [    0.689824] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
> >> [    0.699409] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
> >> [    0.708775] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
> >> [    0.718094] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
> >> [    0.727535] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
> >> [    0.736953] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
> >> [    0.746404] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
> >> [    0.756098] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
> >> [    0.765436] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
> >> [    0.774870] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
> >> [    0.776730] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
> >> [    0.997446] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
> >> [    1.029604] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
> >> [    1.043098] clocksource: Switched to clocksource timer@40000c00
> >> [    1.358086] workingset: timestamp_bits=30 max_order=11 bucket_order=0
> >> [    1.632751] io scheduler mq-deadline registered
> >> [    1.634287] io scheduler kyber registered
> >> [    1.650574] STM32 USART driver initialized
> >> [    1.661272] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000)t
> >> [    2.603317] random: fast init done
> >> [    2.637564] printk: console [ttySTM0] enabled
> >> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
> >> [    2.758986] spi_stm32 40015000.spi: driver initialized
> >> [    2.795733] i2c /dev entries driver
> >> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
> >> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
> >> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
> >> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
> >> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
> >> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
> >> [    3.765208] Console: switching to colour frame buffer device 30x40
> >> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
> >> [    4.212737] Freeing unused kernel memory: 324K
> >> [    4.287300] This architecture does not have kernel memory protection.
> >> [    4.401202] Run /linuxrc as init process
> >> [    4.478622]   with arguments:
> >> [    4.555069]     /linuxrc
> >> [    4.595406]   with environment:
> >> [    4.672213]     HOME=/
> >> [    4.712511]     TERM=linux
> >> [  206.785289] random: crng init done
> >>
> >>
> >>>
> >>> If possible, you can try my suggestion.
> >>> - tar -jxf stm32_rootfs.tar.bz2
> >>> - add stm32_rootfs to your kernel config( enable initramfs)
> >>
> >> As explained above, that's what i did
> >>
> >>> - make O=YOUR_KERNEL_OUT zImage dtbs LOADADDR=0x90008000
> >>
> >>
> >>
> >>> - create itb file (combine dtb and kernel, initramfs) by mkimage
> >>>   ./mkimage -f stm32.its stm32.itb
> >>
> >> I didn't use .itb file, but directly uImage loaded @0x90406000 and stm32f429-disco.dtb loaded @0x90400000
> >
> > It's fine with manual load dtb and uImage.
> >
> >>
> >> How do you generate .its file ?
> >
> > I refer to u-boot doc , U-BOOT-SOURCE/doc/uImage.FIT/kernel.its
> > you can just change the PATH('data = ' filed) of my stm32.its.
> > you can correct bootargs in u-boot, try again
> >
> > good luck.
> >
> > Thanks
> >
> > Best Regards
> > Dillon
> >
> >>
> >>
> >>>   (before above command, make sure you correct stm32.its adapt to your env)
> >>>
> >>> This process will make u-boot to load the kernel more simple.
> >>>
> >>> Thanks.
> >>>
> >>> Best Regards.
> >>> Dillon
> >>>
> >>>
> >>>>
> >>>>
> >>>> I can't test your I2C patch.
> >>>>
> >>>> Patrice
> >>>>
> >>>>
> >>>>> -- setup ts_calibrate running env on stm32f429-disco
> >>>>> / # export TSLIB_CONFFILE=/etc/ts.conf
> >>>>> / # export TSLIB_TSDEVICE=/dev/input/event0
> >>>>> / # export TSLIB_CONSOLEDEVICE=none
> >>>>> / # export TSLIB_FBDEVICE=/dev/fb0
> >>>>>
> >>>>> -- clear screen
> >>>>> / # ./fb
> >>>>>
> >>>>> -- run ts_calibrate
> >>>>> / # ts_calibrate
> >>>>> (you can calibrate touchscreen now, and get below errors)
> >>>>>
> >>>>> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
> >>>>> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
> >>>>> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
> >>>>> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
> >>>>>
> >>>>> ...
> >>>>> with i2c patch applied, you will find below logs:
> >>>>>
> >>>>> RAW---------------------> 3164 908 183 118.110884
> >>>>> TS_READ_RAW----> x = 3164, y =908, pressure = 183
> >>>>> RAW---------------------> 3166 922 126 118.138946
> >>>>> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
> >>>>> ....
> >>>>>
> >>>>> files link:
> >>>>> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> Dillon Min (4):
> >>>>>   drm/panel: Add ilitek ili9341 panel driver
> >>>>>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
> >>>>>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
> >>>>>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
> >>>>>     kernel startup
> >>>>>
> >>>>>  drivers/clk/clk-stm32f4.c                    |   10 +-
> >>>>>  drivers/gpu/drm/panel/Kconfig                |   12 +
> >>>>>  drivers/gpu/drm/panel/Makefile               |    1 +
> >>>>>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
> >>>>>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
> >>>>>  5 files changed, 1310 insertions(+), 10 deletions(-)
> >>>>>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
> >>>>>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform
  2021-06-01  3:28           ` Dillon Min
@ 2021-06-01  8:00             ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2021-06-01  8:00 UTC (permalink / raw)
  To: Dillon Min
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

[-- Attachment #1: Type: text/plain, Size: 18083 bytes --]

Hi Dillon

On 6/1/21 5:28 AM, Dillon Min wrote:
> Hi Patrice
> 
> On Mon, May 31, 2021 at 10:58 PM Patrice CHOTARD
> <patrice.chotard@foss.st.com> wrote:
>>
>> Hi Dillon
>>
>> On 5/31/21 4:29 PM, Dillon Min wrote:
>>> Hi Patrice
>>>
>>> On Mon, May 31, 2021 at 9:51 PM Patrice CHOTARD
>>> <patrice.chotard@foss.st.com> wrote:
>>>>
>>>>
>>>>
>>>> On 5/31/21 3:38 PM, Dillon Min wrote:
>>>>> Hi Patrice
>>>>>
>>>>> Thanks for your time to test my patch.
>>>>>
>>>>> On Mon, May 31, 2021 at 9:20 PM Patrice CHOTARD
>>>>> <patrice.chotard@foss.st.com> wrote:
>>>>>>
>>>>>> Hi Dillon
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
>>>>>>> From: Dillon Min <dillon.minfei@gmail.com>
>>>>>>>
>>>>>>> This seriese fix three i2c/clk bug for stm32 f4/f7
>>>>>>> - kernel runing in sdram, i2c driver get data timeout
>>>>>>> - ltdc clk turn off after kernel console active
>>>>>>> - kernel hang in set ltdc clock rate
>>>>>>>
>>>>>>> clk bug found on stm32f429/f469-disco board
>>>>>>>
>>>>>>> Hi Patrice:
>>>>>>> below is the guide to verify the patch:
>>>>>>>
>>>>>>> setup test env with following files(link at below 'files link'):
>>>>>>> [1] u-boot-dtb.bin
>>>>>>> [2] rootfs zip file (used in kernel initramfs)
>>>>>>> [3] u-boot's mkimage to create itb file
>>>>>>> [4] kernel config file
>>>>>>> [5] my itb with-or-without i2c patch
>>>>>>>
>>>>>>> This patch based on kernel commit:
>>>>>>> 88b06399c9c766c283e070b022b5ceafa4f63f19
>>>>>>>
>>>>>>> Note:
>>>>>>> panel-ilitek-ili9341.c is the driver which was submitted last year, but not
>>>>>>> get accepted. it's used to setup touch screen calibration, then test i2c.
>>>>>>>
>>>>>>> create itb file(please correct path of 'data'):
>>>>>>> ./mkimage -f stm32.its stm32.itb
>>>>>>>
>>>>>>> HW setup:
>>>>>>> console:
>>>>>>>        PA9, PA10
>>>>>>>        usart0
>>>>>>>        serial@40011000
>>>>>>>        115200 8n1
>>>>>>>
>>>>>>> -- flash u-boot.bin to stm32f429-disco on PC
>>>>>>> $ sudo openocd -f board/stm32f429discovery.cfg -c \
>>>>>>>   '{PATH-TO-YOUR-UBOOT}/u-boot-dtb.bin 0x08000000 exit reset'
>>>>>>>
>>>>>>> -- setup kernel load bootargs at u-boot
>>>>>>> U-Boot > setenv bootargs 'console=tty0 console=ttySTM0,115200
>>>>>>>                     root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
>>>>>>> U-Boot > loady;bootm
>>>>>>> (download stm32.dtb or your kernel with itb format, or download zImage, dtb)
>>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks for these informations
>>>>>> I was able to load and boot DTB and uImage directly in SDRAM as you suggested,
>>>>>> i saw Linux logo and kernel log on the STM32F429-disco display,
>>>>>> but i can't reach the login.
>>>>>>
>>>>>> The last kernel log i got is :
>>>>>>
>>>>>> Starting kernel ...
>>>>>>
>>>>>> [    0.000000] Booting Linux on physical CPU 0x0
>>>>>> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
>>>>>> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
>>>>>> [    0.000000] CPU: unknown data cache, unknown instruction cache
>>>>>> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
>>>>>> [    0.000000] Zone ranges:
>>>>>> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
>>>>>> [    0.000000] Movable zone start for each node
>>>>>> [    0.000000] Early memory node ranges
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>> [    2.637564] printk: console [ttySTM0] enabled
>>>>>> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
>>>>>> [    2.758986] spi_stm32 40015000.spi: driver initialized
>>>>>> [    2.795733] i2c /dev entries driver
>>>>>> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
>>>>>> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
>>>>>> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
>>>>>> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
>>>>>> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
>>>>>> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
>>>>>> [    3.765208] Console: switching to colour frame buffer device 30x40
>>>>>> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
>>>>>> [    4.212737] Freeing unused kernel memory: 324K
>>>>>> [    4.287300] This architecture does not have kernel memory protection.
>>>>>> [    4.401202] Run /linuxrc as init process
>>>>>> [    4.478622]   with arguments:
>>>>>> [    4.555069]     /linuxrc
>>>>>> [    4.595406]   with environment:
>>>>>> [    4.672213]     HOME=/
>>>>>> [    4.712511]     TERM=linux
>>>>>> [  206.785289] random: crng init done
>>>>>
>>>>> I guess you didn't add the rootfs to uImage I sent you.
>>>>
>>>> I do use your rootfs
>>>>
>>>>> Could you post all the logs from u-boot startup to kernel log end.
>>>>
>>>>
>>>> U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)
>>>>
>>>> DRAM:  8 MiB
>>>> Flash: 2 MiB
>>>> Loading Environment from Flash... OK
>>>> In:    serial@40011000
>>>> Out:   serial@40011000
>>>> Err:   serial@40011000
>>>> Hit any key to stop autoboot:  0
>>>> U-Boot >    setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/lin'
>>>
>>> It seems bootargs are broken here.
>>> should be setenv bootargs 'console=tty0 console=ttySTM0,115200
>>> root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2'
>>
>> It's just a copy/paste issue from my minicom window to my mailer,
>> but the bootargs is correct ;-)
>>
>> See a correct U-boot/kernel log in attached.
> 
> Yes, your log is ok.
> I tried to follow your way(dtb + uImage) to figure out
> why your kernel was hanging there, but no luck.
> 
> You can find my log from [1] .
> (since my uImage is bigger than yours, i change the
> loadaddr to 0x90300000, 0x90306000)
> 
> but there are some points we can check:
> -  kernel config, you can find my config in [2],
>     could you share yours to me as well, i can based on
>     your configs to test.

Please find my .config attached

> -  uImage size (yours 1593664 bytes is quite smaller than mine, 2072864 bytes
>     the difference based on kernel config and rootfs size)
> -  cross tool chain (upload my toolchain to google drive [3])
> -  could you add initcall_debug to your bootargs, to see more log
>     at kernel startup

I also tried with your toolchain but still the same issue, see the log attached (with initcall_debug in bootargs).

Then i used an another rootfs (attached rootfs_mcu.cpio file) but unfortunately, during the 
rootfs init, some memory allocation are done and failed due to low RAM available on this board. 

The issue seems linked to the rootfs...but i got no clue on what is going wrong with your rootfs ?


Thanks
Patrice



> 
> [1] kernel log based on dtb + uImage
> https://drive.google.com/file/d/1wnA5b3B_6MIb4PWZXn-3DlBbxpi41uSA/view?usp=sharing
> 
> [2] kernel config
> https://drive.google.com/file/d/1oOJt3NRYor3-Uzjpzrujv3uvWguxYQQp/view?usp=sharing
> 
> [3] arm-none-eabi- toolchain
> https://drive.google.com/file/d/1Aq0sF2Gi4y4qaDPnM2S0xCOowFSLZYJm/view?usp=sharing
> 
> Best Regards
> Dillon
> 
>>
>>
>>>
>>>> U-Boot >
>>>> U-Boot >
>>>> U-Boot > setenv loadaddr 0x90400000
>>>> U-Boot > loady
>>>> ## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...
>>>> CxyzModem - CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 7 retries
>>>> ## Total Size      = 0x00004cad = 19629 Bytes
>>>> U-Boot > setenv loadaddr 0x90406000
>>>> U-Boot > loady
>>>> ## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...
>>>> C- CRC mode, 12453(SOH)/0(STX)/0(CAN) packets, 4 retries
>>>> ## Total Size      = 0x00185140 = 1593664 Bytes
>>>> U-Boot > bootm 0x90406000 - 0x90400000
>>>> ## Booting kernel from Legacy Image at 90406000 ...
>>>>    Image Name:   Linux-5.13.0-rc1-00082-g9dbbd5cb
>>>>    Image Type:   ARM Linux Kernel Image (uncompressed)
>>>>    Data Size:    1593600 Bytes = 1.5 MiB
>>>>    Load Address: 90008000
>>>>    Entry Point:  90008000
>>>>    Verifying Checksum ... OK
>>>> ## Flattened Device Tree blob at 90400000
>>>>    Booting using the fdt blob at 0x90400000
>>>>    Loading Kernel Image
>>>>    Loading Device Tree to 905b9000, end 905c0cac ... OK
>>>>
>>>> Starting kernel ...
>>>>
>>>> [    0.000000] Booting Linux on physical CPU 0x0
>>>> [    0.000000] Linux version 5.13.0-rc1-00082-g9dbbd5cb6240-dirty (nxp11987@lmecxl0573.lme1
>>>> [    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
>>>> [    0.000000] CPU: unknown data cache, unknown instruction cache
>>>> [    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
>>>> [    0.000000] Zone ranges:
>>>> [    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
>>>> [    0.000000] Movable zone start for each node
>>>> [    0.000000] Early memory node ranges
>>>> [    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
>>>> [    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
>>>> [    0.000000] On node 0 totalpages: 2048
>>>> [    0.000000]   Normal zone: 16 pages used for memmap
>>>> [    0.000000]   Normal zone: 0 pages reserved
>>>> [    0.000000]   Normal zone: 2048 pages, LIFO batch:0
>>>> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
>>>> [    0.000000] pcpu-alloc: [0] 0
>>>> [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
>>>> [    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdin2
>>>
>>> ditto
>>
>> same explanation as above, the command line displayed is truncated, but it is the one expected.
>>
>>
>>>
>>>> [    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>>>> [    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>>>> [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
>>>> [    0.000000] Memory: 5264K/8192K available (1372K kernel code, 302K rwdata, 516K rodata,)
>>>> [    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
>>>> [    0.000000] rcu: Preemptible hierarchical RCU implementation.
>>>> [    0.000000] rcu:     RCU event tracing is enabled.
>>>> [    0.000000]  Trampoline variant of Tasks RCU enabled.
>>>> [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
>>>> [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
>>>> [    0.000000] /soc/interrupt-controller@40013c00: bank0
>>>> [    0.000000] random: get_random_bytes called from start_kernel+0x203/0x370 with crng_ini0
>>>> [    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idls
>>>> [    0.000000] ARM System timer initialized as clocksource
>>>> [    0.000026] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
>>>> [    0.000665] timer@40000c00: STM32 sched_clock registered
>>>> [    0.001275] Switching to timer-based delay loop, resolution 11ns
>>>> [    0.001712] timer@40000c00: STM32 delay timer registered
>>>> [    0.002253] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_is
>>>> [    0.003076] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
>>>> [    0.014135] Console: colour dummy device 80x30
>>>> [    0.062375] printk: console [tty0] enabled
>>>> [    0.063843] Calibrating delay loop (skipped), value calculated using timer frequency.. )
>>>> [    0.066453] pid_max: default: 4096 minimum: 301
>>>> [    0.071393] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>>>> [    0.073734] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
>>>> [    0.104759] rcu: Hierarchical SRCU implementation.
>>>> [    0.111552] devtmpfs: initialized
>>>> [    0.339332] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns:s
>>>> [    0.341835] pinctrl core: initialized pinctrl subsystem
>>>> [    0.658423] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
>>>> [    0.680505] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
>>>> [    0.689824] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
>>>> [    0.699409] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
>>>> [    0.708775] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
>>>> [    0.718094] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
>>>> [    0.727535] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
>>>> [    0.736953] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
>>>> [    0.746404] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
>>>> [    0.756098] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
>>>> [    0.765436] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
>>>> [    0.774870] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
>>>> [    0.776730] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
>>>> [    0.997446] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
>>>> [    1.029604] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
>>>> [    1.043098] clocksource: Switched to clocksource timer@40000c00
>>>> [    1.358086] workingset: timestamp_bits=30 max_order=11 bucket_order=0
>>>> [    1.632751] io scheduler mq-deadline registered
>>>> [    1.634287] io scheduler kyber registered
>>>> [    1.650574] STM32 USART driver initialized
>>>> [    1.661272] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000)t
>>>> [    2.603317] random: fast init done
>>>> [    2.637564] printk: console [ttySTM0] enabled
>>>> [    2.747984] panel-ilitek-ili9341 spi0.1: get optional vcc failed
>>>> [    2.758986] spi_stm32 40015000.spi: driver initialized
>>>> [    2.795733] i2c /dev entries driver
>>>> [    2.849955] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
>>>> [    2.922030] stmpe-ts stmpe-ts: DMA mask not set
>>>> [    2.965729] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts0
>>>> [    2.991570] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
>>>> [    3.058262] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on min0
>>>> [    3.665951] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
>>>> [    3.765208] Console: switching to colour frame buffer device 30x40
>>>> [    4.014269] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffere
>>>> [    4.212737] Freeing unused kernel memory: 324K
>>>> [    4.287300] This architecture does not have kernel memory protection.
>>>> [    4.401202] Run /linuxrc as init process
>>>> [    4.478622]   with arguments:
>>>> [    4.555069]     /linuxrc
>>>> [    4.595406]   with environment:
>>>> [    4.672213]     HOME=/
>>>> [    4.712511]     TERM=linux
>>>> [  206.785289] random: crng init done
>>>>
>>>>
>>>>>
>>>>> If possible, you can try my suggestion.
>>>>> - tar -jxf stm32_rootfs.tar.bz2
>>>>> - add stm32_rootfs to your kernel config( enable initramfs)
>>>>
>>>> As explained above, that's what i did
>>>>
>>>>> - make O=YOUR_KERNEL_OUT zImage dtbs LOADADDR=0x90008000
>>>>
>>>>
>>>>
>>>>> - create itb file (combine dtb and kernel, initramfs) by mkimage
>>>>>   ./mkimage -f stm32.its stm32.itb
>>>>
>>>> I didn't use .itb file, but directly uImage loaded @0x90406000 and stm32f429-disco.dtb loaded @0x90400000
>>>
>>> It's fine with manual load dtb and uImage.
>>>
>>>>
>>>> How do you generate .its file ?
>>>
>>> I refer to u-boot doc , U-BOOT-SOURCE/doc/uImage.FIT/kernel.its
>>> you can just change the PATH('data = ' filed) of my stm32.its.
>>> you can correct bootargs in u-boot, try again
>>>
>>> good luck.
>>>
>>> Thanks
>>>
>>> Best Regards
>>> Dillon
>>>
>>>>
>>>>
>>>>>   (before above command, make sure you correct stm32.its adapt to your env)
>>>>>
>>>>> This process will make u-boot to load the kernel more simple.
>>>>>
>>>>> Thanks.
>>>>>
>>>>> Best Regards.
>>>>> Dillon
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>> I can't test your I2C patch.
>>>>>>
>>>>>> Patrice
>>>>>>
>>>>>>
>>>>>>> -- setup ts_calibrate running env on stm32f429-disco
>>>>>>> / # export TSLIB_CONFFILE=/etc/ts.conf
>>>>>>> / # export TSLIB_TSDEVICE=/dev/input/event0
>>>>>>> / # export TSLIB_CONSOLEDEVICE=none
>>>>>>> / # export TSLIB_FBDEVICE=/dev/fb0
>>>>>>>
>>>>>>> -- clear screen
>>>>>>> / # ./fb
>>>>>>>
>>>>>>> -- run ts_calibrate
>>>>>>> / # ts_calibrate
>>>>>>> (you can calibrate touchscreen now, and get below errors)
>>>>>>>
>>>>>>> [  113.942087] stmpe-i2c0-0041: failed to read regs 0x52: -110
>>>>>>> [  114.063598] stmpe-i2c 0-0041: failed to read reg 0x4b: -16
>>>>>>> [  114.185629] stmpe-i2c 0-0041: failed to read reg 0x40: -16
>>>>>>> [  114.307257] stmpe-i2c 0-0041: failed to write reg 0xb: -16
>>>>>>>
>>>>>>> ...
>>>>>>> with i2c patch applied, you will find below logs:
>>>>>>>
>>>>>>> RAW---------------------> 3164 908 183 118.110884
>>>>>>> TS_READ_RAW----> x = 3164, y =908, pressure = 183
>>>>>>> RAW---------------------> 3166 922 126 118.138946
>>>>>>> TS_READ_RAW----> x = 3166, y = 922, pressure = 126
>>>>>>> ....
>>>>>>>
>>>>>>> files link:
>>>>>>> https://drive.google.com/drive/folders/1qNbjChcB6UGtKzne2F5x9_WG_sZFyo3o?usp=sharing
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Dillon Min (4):
>>>>>>>   drm/panel: Add ilitek ili9341 panel driver
>>>>>>>   i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
>>>>>>>   clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
>>>>>>>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
>>>>>>>     kernel startup
>>>>>>>
>>>>>>>  drivers/clk/clk-stm32f4.c                    |   10 +-
>>>>>>>  drivers/gpu/drm/panel/Kconfig                |   12 +
>>>>>>>  drivers/gpu/drm/panel/Makefile               |    1 +
>>>>>>>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1285 ++++++++++++++++++++++++++
>>>>>>>  drivers/i2c/busses/i2c-stm32f4.c             |   12 +-
>>>>>>>  5 files changed, 1310 insertions(+), 10 deletions(-)
>>>>>>>  create mode 100755 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
>>>>>>>

[-- Attachment #2: .config --]
[-- Type: text/plain, Size: 52485 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 5.13.0-rc1 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=100201
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23501
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23501
CONFIG_LLD_VERSION=0
CONFIG_CC_HAS_ASM_GOTO=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
# CONFIG_SYSVIPC is not set
# CONFIG_WATCH_QUEUE is not set
# CONFIG_USELIB is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
# end of IRQ subsystem

CONFIG_GENERIC_CLOCKEVENTS=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
# CONFIG_NO_HZ is not set
CONFIG_HIGH_RES_TIMERS=y
# end of Timers subsystem

# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_PSI is not set
# end of CPU/Task time and stats accounting

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
CONFIG_PREEMPT_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
CONFIG_TREE_SRCU=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_TASKS_RCU=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_NEED_SEGCBLIST=y
# end of RCU Subsystem

# CONFIG_IKCONFIG is not set
# CONFIG_IKHEADERS is not set
CONFIG_LOG_BUF_SHIFT=16
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_GENERIC_SCHED_CLOCK=y

#
# Scheduler features
#
# end of Scheduler features

# CONFIG_CGROUPS is not set
# CONFIG_NAMESPACES is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="/local/home/nxp11987/Downloads/STM32F429-disco_binaires_issue_clk_i2c/stm32_rootfs.tar.bz2"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_RD_ZSTD is not set
CONFIG_INITRAMFS_COMPRESSION_GZIP=y
# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
# CONFIG_BOOT_CONFIG is not set
# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_LD_ORPHAN_WARN=y
CONFIG_SYSCTL=y
CONFIG_HAVE_UID16=y
CONFIG_EXPERT=y
# CONFIG_UID16 is not set
CONFIG_MULTIUSER=y
# CONFIG_SGETMASK_SYSCALL is not set
CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_PRINTK_NMI=y
CONFIG_BUG=y
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
CONFIG_TIMERFD=y
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_BASE_RELATIVE=y
# CONFIG_BPF_SYSCALL is not set
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_KCMP=y
CONFIG_RSEQ=y
# CONFIG_DEBUG_RSEQ is not set
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
# CONFIG_PC104 is not set

#
# Kernel Performance Events And Counters
#
# CONFIG_PERF_EVENTS is not set
# end of Kernel Performance Events And Counters

# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLUB_DEBUG is not set
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
# CONFIG_SLAB_FREELIST_HARDENED is not set
# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
# CONFIG_PROFILING is not set
# end of General setup

CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_NO_IOPORT_MAP=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_PHYS_OFFSET=0x90000000
CONFIG_GENERIC_BUG=y
CONFIG_PGTABLE_LEVELS=2

#
# System Type
#
# CONFIG_MMU is not set
CONFIG_ARCH_MMAP_RND_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_BITS_MAX=16
CONFIG_ARM_SINGLE_ARMV7M=y
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_DOVE is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C24XX is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_MXC is not set
CONFIG_ARCH_STM32=y
CONFIG_MACH_STM32F429=y
# CONFIG_MACH_STM32F469 is not set
# CONFIG_MACH_STM32F746 is not set
# CONFIG_MACH_STM32F769 is not set
# CONFIG_MACH_STM32H743 is not set
# CONFIG_ARCH_LPC18XX is not set
# CONFIG_ARCH_MPS2 is not set

#
# Processor Type
#
CONFIG_CPU_V7M=y
CONFIG_CPU_THUMBONLY=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_32v7M=y
CONFIG_CPU_ABRT_NOMMU=y
CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_CACHE_NOP=y
CONFIG_CPU_CACHE_V7M=y
CONFIG_CPU_V7M_NUM_IRQ=240

#
# Processor Features
#
CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_DMA_MEM_BUFFERABLE=y
CONFIG_SET_MEM_PARAM=y
CONFIG_DRAM_BASE=0x90000000
CONFIG_DRAM_SIZE=0x00800000
# CONFIG_REMAP_VECTORS_TO_RAM is not set
# CONFIG_ARM_MPU is not set
# end of System Type

#
# Bus support
#
# end of Bus support

#
# Kernel Features
#
CONFIG_PAGE_OFFSET=0x90000000
CONFIG_ARCH_NR_GPIO=0
CONFIG_HZ_FIXED=0
CONFIG_HZ_100=y
# CONFIG_HZ_200 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_500 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
CONFIG_THUMB2_KERNEL=y
CONFIG_AEABI=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_FORCE_MAX_ZONEORDER=11
# CONFIG_PARAVIRT is not set
# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
# end of Kernel Features

#
# Boot options
#
CONFIG_USE_OF=y
# CONFIG_ATAGS is not set
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
# CONFIG_ARM_APPENDED_DTB is not set
CONFIG_CMDLINE=""
# CONFIG_XIP_KERNEL is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_AUTO_ZRELADDR=y
# end of Boot options

#
# CPU Power Management
#

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
# end of CPU Frequency scaling

#
# CPU Idle
#
# CONFIG_CPU_IDLE is not set
# end of CPU Idle
# end of CPU Power Management

#
# Floating point emulation
#

#
# At least one emulation must be selected
#
# end of Floating point emulation

#
# Power management options
#
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_SUSPEND_SKIP_SYNC is not set
CONFIG_PM_SLEEP=y
# CONFIG_PM_AUTOSLEEP is not set
# CONFIG_PM_WAKELOCKS is not set
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
# CONFIG_APM_EMULATION is not set
CONFIG_PM_CLK=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_CPU_PM=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARM_CPU_SUSPEND=y
# end of Power management options

#
# Firmware Drivers
#
# CONFIG_FIRMWARE_MEMMAP is not set
# CONFIG_GOOGLE_FIRMWARE is not set

#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers

# CONFIG_ARM_CRYPTO is not set
CONFIG_AS_VFP_VMRS_FPINST=y

#
# General architecture-dependent options
#
CONFIG_SET_FS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_NMI=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_KEEPINITRD=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP=y
CONFIG_HAVE_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_LTO_NONE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_ARCH_HAS_PHYS_TO_DMA=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_HAVE_ARCH_PFN_VALID=y

#
# GCOV-based kernel profiling
#
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling

CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_GCC_PLUGINS=y
# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set
# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set
# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
# CONFIG_BLK_DEV_ZONED is not set
# CONFIG_BLK_CMDLINE_PARSER is not set
# CONFIG_BLK_WBT is not set
# CONFIG_BLK_SED_OPAL is not set
# CONFIG_BLK_INLINE_ENCRYPTION is not set

#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_EFI_PARTITION=y
# end of Partition Types

CONFIG_BLK_PM=y

#
# IO Schedulers
#
CONFIG_MQ_IOSCHED_DEADLINE=y
CONFIG_MQ_IOSCHED_KYBER=y
# CONFIG_IOSCHED_BFQ is not set
# end of IO Schedulers

CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_FREEZER=y

#
# Executable file formats
#
CONFIG_BINFMT_ELF_FDPIC=y
CONFIG_ELFCORE=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_ARCH_HAS_BINFMT_FLAT=y
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
# CONFIG_BINFMT_FLAT_OLD is not set
# CONFIG_BINFMT_ZFLAT is not set
CONFIG_BINFMT_SHARED_FLAT=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_COREDUMP is not set
# end of Executable file formats

#
# Memory Management options
#
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_SPLIT_PTLOCK_CPUS=999999
# CONFIG_PAGE_REPORTING is not set
CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
CONFIG_NEED_PER_CPU_KM=y
# CONFIG_CLEANCACHE is not set
# CONFIG_ZPOOL is not set
# CONFIG_ZBUD is not set
CONFIG_GENERIC_EARLY_IOREMAP=y
# CONFIG_PERCPU_STATS is not set

#
# GUP_TEST needs to have DEBUG_FS enabled
#
# end of Memory Management options

# CONFIG_NET is not set
CONFIG_HAVE_EBPF_JIT=y

#
# Device Drivers
#
CONFIG_ARM_AMBA=y
# CONFIG_PCCARD is not set

#
# Generic Driver Options
#
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y

#
# Firmware loader
#
# CONFIG_FW_LOADER is not set
# end of Firmware loader

CONFIG_ALLOW_DEV_COREDUMP=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_DMA_SHARED_BUFFER=y
# CONFIG_DMA_FENCE_TRACE is not set
# end of Generic Driver Options

#
# Bus devices
#
# CONFIG_BRCMSTB_GISB_ARB is not set
# CONFIG_MOXTET is not set
# CONFIG_SIMPLE_PM_BUS is not set
# CONFIG_VEXPRESS_CONFIG is not set
# CONFIG_MHI_BUS is not set
# end of Bus devices

# CONFIG_GNSS is not set
# CONFIG_MTD is not set
CONFIG_DTC=y
CONFIG_OF=y
# CONFIG_OF_UNITTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_RESERVED_MEM=y
# CONFIG_OF_OVERLAY is not set
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set

#
# NVME Support
#
# CONFIG_NVME_FC is not set
# end of NVME Support

#
# Misc devices
#
# CONFIG_AD525X_DPOT is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_APDS9802ALS is not set
# CONFIG_ISL29003 is not set
# CONFIG_ISL29020 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_SENSORS_APDS990X is not set
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_SRAM is not set
# CONFIG_XILINX_SDFEC is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_MAX6875 is not set
CONFIG_EEPROM_93CX6=y
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_IDT_89HPESX is not set
# CONFIG_EEPROM_EE1004 is not set
# end of EEPROM support

#
# Texas Instruments shared transport line discipline
#
# end of Texas Instruments shared transport line discipline

# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_SENSORS_LIS3_I2C is not set
# CONFIG_ALTERA_STAPL is not set
# CONFIG_ECHO is not set
# CONFIG_PVPANIC is not set
# end of Misc devices

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# end of SCSI device support

# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set
# CONFIG_NVM is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_MATRIXKMAP is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_AD7877 is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_TOUCHSCREEN_AR1021_I2C is not set
# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
# CONFIG_TOUCHSCREEN_BU21013 is not set
# CONFIG_TOUCHSCREEN_BU21029 is not set
# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set
# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set
# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
# CONFIG_TOUCHSCREEN_DYNAPRO is not set
# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
# CONFIG_TOUCHSCREEN_EETI is not set
# CONFIG_TOUCHSCREEN_EGALAX is not set
# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set
# CONFIG_TOUCHSCREEN_EXC3000 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GOODIX is not set
# CONFIG_TOUCHSCREEN_HIDEEP is not set
# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_ILITEK is not set
# CONFIG_TOUCHSCREEN_S6SY761 is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_EKTF2127 is not set
# CONFIG_TOUCHSCREEN_ELAN is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
# CONFIG_TOUCHSCREEN_MAX11801 is not set
# CONFIG_TOUCHSCREEN_MCS5000 is not set
# CONFIG_TOUCHSCREEN_MMS114 is not set
# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set
# CONFIG_TOUCHSCREEN_MSG2638 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_PIXCIR is not set
# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
# CONFIG_TOUCHSCREEN_TSC2004 is not set
# CONFIG_TOUCHSCREEN_TSC2005 is not set
# CONFIG_TOUCHSCREEN_TSC2007 is not set
# CONFIG_TOUCHSCREEN_RM_TS is not set
# CONFIG_TOUCHSCREEN_SILEAD is not set
# CONFIG_TOUCHSCREEN_SIS_I2C is not set
# CONFIG_TOUCHSCREEN_ST1232 is not set
CONFIG_TOUCHSCREEN_STMPE=y
# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set
# CONFIG_TOUCHSCREEN_SX8654 is not set
# CONFIG_TOUCHSCREEN_TPS6507X is not set
# CONFIG_TOUCHSCREEN_ZET6223 is not set
# CONFIG_TOUCHSCREEN_ZFORCE is not set
# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
# CONFIG_TOUCHSCREEN_IQS5XX is not set
# CONFIG_TOUCHSCREEN_ZINITIX is not set
# CONFIG_INPUT_MISC is not set
# CONFIG_RMI4_CORE is not set

#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
# end of Hardware I/O ports
# end of Input device support

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_UNIX98_PTYS is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_LDISC_AUTOLOAD=y

#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SERIAL_UARTLITE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_SIFIVE is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_SC16IS7XX is not set
# CONFIG_SERIAL_BCM63XX is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_SERIAL_FSL_LINFLEXUART is not set
# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
# CONFIG_SERIAL_ST_ASC is not set
# CONFIG_SERIAL_SPRD is not set
CONFIG_SERIAL_STM32=y
CONFIG_SERIAL_STM32_CONSOLE=y
# end of Serial drivers

CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_N_HDLC is not set
# CONFIG_NULL_TTY is not set
# CONFIG_HVC_DCC is not set
# CONFIG_SERIAL_DEV_BUS is not set
# CONFIG_TTY_PRINTK is not set
# CONFIG_VIRTIO_CONSOLE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_IPMB_DEVICE_INTERFACE is not set
# CONFIG_HW_RANDOM is not set
CONFIG_DEVMEM=y
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_XILLYBUS is not set
# end of Character devices

# CONFIG_RANDOM_TRUST_BOOTLOADER is not set

#
# I2C support
#
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_MUX is not set
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y

#
# I2C Hardware Bus support
#

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_CBUS_GPIO is not set
# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
# CONFIG_I2C_EMEV2 is not set
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_NOMADIK is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_RK3X is not set
# CONFIG_I2C_SIMTEC is not set
CONFIG_I2C_STM32F4=y
# CONFIG_I2C_STM32F7 is not set
# CONFIG_I2C_XILINX is not set

#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_TAOS_EVM is not set

#
# Other I2C/SMBus bus drivers
#
# end of I2C Hardware Bus support

CONFIG_I2C_SLAVE=y
# CONFIG_I2C_SLAVE_EEPROM is not set
# CONFIG_I2C_SLAVE_TESTUNIT is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# end of I2C support

# CONFIG_I3C is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
# CONFIG_SPI_MEM is not set

#
# SPI Master Controller Drivers
#
# CONFIG_SPI_ALTERA is not set
# CONFIG_SPI_ALTERA_CORE is not set
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_CADENCE is not set
# CONFIG_SPI_CADENCE_QUADSPI is not set
# CONFIG_SPI_DESIGNWARE is not set
# CONFIG_SPI_NXP_FLEXSPI is not set
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_FSL_SPI is not set
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_ROCKCHIP is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_SIFIVE is not set
CONFIG_SPI_STM32=y
# CONFIG_SPI_STM32_QSPI is not set
# CONFIG_SPI_MXIC is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_ZYNQMP_GQSPI is not set
# CONFIG_SPI_AMD is not set

#
# SPI Multiplexer support
#
# CONFIG_SPI_MUX is not set

#
# SPI Protocol Masters
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_SPI_SLAVE is not set
# CONFIG_SPMI is not set
# CONFIG_HSI is not set
# CONFIG_PPS is not set

#
# PTP clock support
#

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
# end of PTP clock support

CONFIG_PINCTRL=y
CONFIG_PINMUX=y
CONFIG_PINCONF=y
CONFIG_GENERIC_PINCONF=y
# CONFIG_DEBUG_PINCTRL is not set
# CONFIG_PINCTRL_MCP23S08 is not set
# CONFIG_PINCTRL_SINGLE is not set
# CONFIG_PINCTRL_SX150X is not set
# CONFIG_PINCTRL_STMFX is not set
# CONFIG_PINCTRL_OCELOT is not set
# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set

#
# Renesas pinctrl drivers
#
# end of Renesas pinctrl drivers

CONFIG_PINCTRL_STM32=y
CONFIG_PINCTRL_STM32F429=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_FASTPATH_LIMIT=512
CONFIG_OF_GPIO=y
CONFIG_GPIOLIB_IRQCHIP=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_CDEV_V1=y

#
# Memory mapped GPIO drivers
#
# CONFIG_GPIO_74XX_MMIO is not set
# CONFIG_GPIO_ALTERA is not set
# CONFIG_GPIO_CADENCE is not set
# CONFIG_GPIO_DWAPB is not set
# CONFIG_GPIO_FTGPIO010 is not set
# CONFIG_GPIO_GENERIC_PLATFORM is not set
# CONFIG_GPIO_GRGPIO is not set
# CONFIG_GPIO_HLWD is not set
# CONFIG_GPIO_LOGICVC is not set
# CONFIG_GPIO_MB86S7X is not set
# CONFIG_GPIO_MPC8XXX is not set
# CONFIG_GPIO_PL061 is not set
# CONFIG_GPIO_SAMA5D2_PIOBU is not set
# CONFIG_GPIO_SIFIVE is not set
# CONFIG_GPIO_SYSCON is not set
# CONFIG_GPIO_XILINX is not set
# CONFIG_GPIO_ZEVIO is not set
# CONFIG_GPIO_AMD_FCH is not set
# end of Memory mapped GPIO drivers

#
# I2C GPIO expanders
#
# CONFIG_GPIO_ADP5588 is not set
# CONFIG_GPIO_ADNP is not set
# CONFIG_GPIO_GW_PLD is not set
# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCA9570 is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_TPIC2810 is not set
# end of I2C GPIO expanders

#
# MFD GPIO expanders
#
# CONFIG_HTC_EGPIO is not set
CONFIG_GPIO_STMPE=y
# end of MFD GPIO expanders

#
# SPI GPIO expanders
#
# CONFIG_GPIO_74X164 is not set
# CONFIG_GPIO_MAX3191X is not set
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_PISOSR is not set
# CONFIG_GPIO_XRA1403 is not set
# end of SPI GPIO expanders

#
# Virtual GPIO drivers
#
# CONFIG_GPIO_AGGREGATOR is not set
# CONFIG_GPIO_MOCKUP is not set
# end of Virtual GPIO drivers

# CONFIG_W1 is not set
# CONFIG_POWER_RESET is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_ACT8945A is not set
# CONFIG_MFD_AS3711 is not set
# CONFIG_MFD_AS3722 is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_AAT2870_CORE is not set
# CONFIG_MFD_ATMEL_FLEXCOM is not set
# CONFIG_MFD_ATMEL_HLCDC is not set
# CONFIG_MFD_BCM590XX is not set
# CONFIG_MFD_BD9571MWV is not set
# CONFIG_MFD_AXP20X_I2C is not set
# CONFIG_MFD_MADERA is not set
# CONFIG_MFD_ASIC3 is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_MFD_DA9055 is not set
# CONFIG_MFD_DA9062 is not set
# CONFIG_MFD_DA9063 is not set
# CONFIG_MFD_DA9150 is not set
# CONFIG_MFD_GATEWORKS_GSC is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_MFD_MP2629 is not set
# CONFIG_MFD_HI6421_PMIC is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_HTC_I2CPLD is not set
# CONFIG_MFD_IQS62X is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_88PM800 is not set
# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_MAX14577 is not set
# CONFIG_MFD_MAX77620 is not set
# CONFIG_MFD_MAX77650 is not set
# CONFIG_MFD_MAX77686 is not set
# CONFIG_MFD_MAX77693 is not set
# CONFIG_MFD_MAX77843 is not set
# CONFIG_MFD_MAX8907 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
# CONFIG_MFD_MT6360 is not set
# CONFIG_MFD_MT6397 is not set
# CONFIG_MFD_MENF21BMC is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_MFD_CPCAP is not set
# CONFIG_MFD_NTXEC is not set
# CONFIG_MFD_RETU is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_PM8XXX is not set
# CONFIG_MFD_RT5033 is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_RK808 is not set
# CONFIG_MFD_RN5T618 is not set
# CONFIG_MFD_SEC_CORE is not set
# CONFIG_MFD_SI476X_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_SKY81452 is not set
CONFIG_MFD_STMPE=y

#
# STMicroelectronics STMPE Interface Drivers
#
CONFIG_STMPE_I2C=y
# CONFIG_STMPE_SPI is not set
# end of STMicroelectronics STMPE Interface Drivers

CONFIG_MFD_SYSCON=y
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_LP3943 is not set
# CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_TI_LMU is not set
# CONFIG_MFD_PALMAS is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
# CONFIG_MFD_TPS65086 is not set
# CONFIG_MFD_TPS65090 is not set
# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TI_LP873X is not set
# CONFIG_MFD_TI_LP87565 is not set
# CONFIG_MFD_TPS65218 is not set
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_TPS80031 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_MFD_LM3533 is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_MFD_TQMX86 is not set
# CONFIG_MFD_LOCHNAGAR is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_ROHM_BD718XX is not set
# CONFIG_MFD_ROHM_BD70528 is not set
# CONFIG_MFD_ROHM_BD71828 is not set
# CONFIG_MFD_ROHM_BD957XMUF is not set
# CONFIG_MFD_STM32_LPTIMER is not set
CONFIG_MFD_STM32_TIMERS=y
# CONFIG_MFD_STPMIC1 is not set
# CONFIG_MFD_STMFX is not set
# CONFIG_MFD_ATC260X_I2C is not set
# CONFIG_MFD_INTEL_M10_BMC is not set
# end of Multifunction device drivers

# CONFIG_REGULATOR is not set
# CONFIG_RC_CORE is not set
# CONFIG_MEDIA_CEC_SUPPORT is not set
# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
CONFIG_DRM=y
CONFIG_DRM_MIPI_DBI=y
# CONFIG_DRM_DP_AUX_CHARDEV is not set
# CONFIG_DRM_DEBUG_MM is not set
# CONFIG_DRM_DEBUG_SELFTEST is not set
CONFIG_DRM_KMS_HELPER=y
CONFIG_DRM_KMS_FB_HELPER=y
# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set
# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
# CONFIG_DRM_DP_CEC is not set
CONFIG_DRM_GEM_CMA_HELPER=y
CONFIG_DRM_KMS_CMA_HELPER=y

#
# I2C encoder or helper chips
#
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
# CONFIG_DRM_I2C_NXP_TDA998X is not set
# CONFIG_DRM_I2C_NXP_TDA9950 is not set
# end of I2C encoder or helper chips

#
# ARM devices
#
# CONFIG_DRM_HDLCD is not set
# CONFIG_DRM_MALI_DISPLAY is not set
# CONFIG_DRM_KOMEDA is not set
# end of ARM devices

# CONFIG_DRM_VGEM is not set
# CONFIG_DRM_VKMS is not set
# CONFIG_DRM_RCAR_DW_HDMI is not set
# CONFIG_DRM_RCAR_LVDS is not set
# CONFIG_DRM_TILCDC is not set
# CONFIG_DRM_FSL_DCU is not set
CONFIG_DRM_STM=y
# CONFIG_DRM_STM_DSI is not set
CONFIG_DRM_PANEL=y

#
# Display Panels
#
# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set
# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
# CONFIG_DRM_PANEL_LVDS is not set
# CONFIG_DRM_PANEL_SIMPLE is not set
# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
CONFIG_DRM_PANEL_ILITEK_ILI9341=y
# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
# CONFIG_DRM_PANEL_LG_LG4573 is not set
# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
# CONFIG_DRM_PANEL_TPO_TPG110 is not set
# end of Display Panels

CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y

#
# Display Interface Bridges
#
# CONFIG_DRM_CDNS_DSI is not set
# CONFIG_DRM_CHIPONE_ICN6211 is not set
# CONFIG_DRM_CHRONTEL_CH7033 is not set
# CONFIG_DRM_DISPLAY_CONNECTOR is not set
# CONFIG_DRM_LONTIUM_LT8912B is not set
# CONFIG_DRM_LONTIUM_LT9611 is not set
# CONFIG_DRM_LONTIUM_LT9611UXC is not set
# CONFIG_DRM_LVDS_CODEC is not set
# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
# CONFIG_DRM_NWL_MIPI_DSI is not set
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_PARADE_PS8640 is not set
# CONFIG_DRM_SIL_SII8620 is not set
# CONFIG_DRM_SII902X is not set
# CONFIG_DRM_SII9234 is not set
# CONFIG_DRM_SIMPLE_BRIDGE is not set
# CONFIG_DRM_THINE_THC63LVD1024 is not set
# CONFIG_DRM_TOSHIBA_TC358762 is not set
# CONFIG_DRM_TOSHIBA_TC358764 is not set
# CONFIG_DRM_TOSHIBA_TC358767 is not set
# CONFIG_DRM_TOSHIBA_TC358768 is not set
# CONFIG_DRM_TOSHIBA_TC358775 is not set
# CONFIG_DRM_TI_TFP410 is not set
# CONFIG_DRM_TI_SN65DSI86 is not set
# CONFIG_DRM_TI_TPD12S015 is not set
# CONFIG_DRM_ANALOGIX_ANX6345 is not set
# CONFIG_DRM_ANALOGIX_ANX78XX is not set
# CONFIG_DRM_ANALOGIX_ANX7625 is not set
# CONFIG_DRM_I2C_ADV7511 is not set
# CONFIG_DRM_CDNS_MHDP8546 is not set
# end of Display Interface Bridges

# CONFIG_DRM_MXSFB is not set
# CONFIG_DRM_ARCPGU is not set
# CONFIG_TINYDRM_HX8357D is not set
# CONFIG_TINYDRM_ILI9225 is not set
# CONFIG_TINYDRM_ILI9341 is not set
# CONFIG_TINYDRM_ILI9486 is not set
# CONFIG_TINYDRM_MI0283QT is not set
# CONFIG_TINYDRM_REPAPER is not set
# CONFIG_TINYDRM_ST7586 is not set
# CONFIG_TINYDRM_ST7735R is not set
# CONFIG_DRM_PL111 is not set
# CONFIG_DRM_TIDSS is not set
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y

#
# Frame buffer Devices
#
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA=y
# CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set

#
# Frame buffer hardware drivers
#
# CONFIG_FB_ARMCLCD is not set
# CONFIG_FB_OPENCORES is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_IBM_GXT4500 is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_SIMPLE is not set
# CONFIG_FB_SSD1307 is not set
# end of Frame buffer Devices

#
# Backlight & LCD device support
#
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_KTD253 is not set
# CONFIG_BACKLIGHT_QCOM_WLED is not set
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
# CONFIG_BACKLIGHT_LM3639 is not set
# CONFIG_BACKLIGHT_GPIO is not set
# CONFIG_BACKLIGHT_LV5207LP is not set
# CONFIG_BACKLIGHT_BD6107 is not set
# CONFIG_BACKLIGHT_ARCXCNN is not set
# end of Backlight & LCD device support

CONFIG_VIDEOMODE_HELPERS=y
CONFIG_HDMI=y

#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
# end of Console display driver support

CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
# end of Graphics support

# CONFIG_SOUND is not set

#
# HID support
#
# CONFIG_HID is not set

#
# I2C HID support
#
# CONFIG_I2C_HID_OF is not set
# CONFIG_I2C_HID_OF_GOODIX is not set
# end of I2C HID support
# end of HID support

CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set

#
# DMA Devices
#
CONFIG_DMA_ENGINE=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DMA_OF=y
# CONFIG_ALTERA_MSGDMA is not set
# CONFIG_AMBA_PL08X is not set
# CONFIG_DW_AXI_DMAC is not set
# CONFIG_FSL_EDMA is not set
# CONFIG_FSL_QDMA is not set
# CONFIG_INTEL_IDMA64 is not set
# CONFIG_NBPFAXI_DMA is not set
# CONFIG_PL330_DMA is not set
CONFIG_STM32_DMA=y
CONFIG_STM32_DMAMUX=y
CONFIG_STM32_MDMA=y
# CONFIG_XILINX_ZYNQMP_DPDMA is not set
# CONFIG_QCOM_HIDMA_MGMT is not set
# CONFIG_QCOM_HIDMA is not set
# CONFIG_DW_DMAC is not set
# CONFIG_SF_PDMA is not set

#
# DMA Clients
#
# CONFIG_ASYNC_TX_DMA is not set
# CONFIG_DMATEST is not set

#
# DMABUF options
#
CONFIG_SYNC_FILE=y
# CONFIG_DMABUF_MOVE_NOTIFY is not set
# CONFIG_DMABUF_DEBUG is not set
# CONFIG_DMABUF_SELFTESTS is not set
# CONFIG_DMABUF_HEAPS is not set
# end of DMABUF options

# CONFIG_AUXDISPLAY is not set
# CONFIG_VFIO is not set
# CONFIG_VIRT_DRIVERS is not set
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VHOST_MENU is not set

#
# Microsoft Hyper-V guest support
#
# end of Microsoft Hyper-V guest support

# CONFIG_GREYBUS is not set
# CONFIG_COMEDI is not set
# CONFIG_STAGING is not set
# CONFIG_GOLDFISH is not set
# CONFIG_CHROME_PLATFORMS is not set
# CONFIG_MELLANOX_PLATFORM is not set
CONFIG_HAVE_CLK=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
# CONFIG_COMMON_CLK_MAX9485 is not set
# CONFIG_COMMON_CLK_SI5341 is not set
# CONFIG_COMMON_CLK_SI5351 is not set
# CONFIG_COMMON_CLK_SI514 is not set
# CONFIG_COMMON_CLK_SI544 is not set
# CONFIG_COMMON_CLK_SI570 is not set
# CONFIG_COMMON_CLK_CDCE706 is not set
# CONFIG_COMMON_CLK_CDCE925 is not set
# CONFIG_COMMON_CLK_CS2000_CP is not set
# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
# CONFIG_COMMON_CLK_VC5 is not set
CONFIG_COMMON_CLK_STM32F=y
# CONFIG_COMMON_CLK_FIXED_MMIO is not set
# CONFIG_XILINX_VCU is not set
# CONFIG_HWSPINLOCK is not set

#
# Clock Source drivers
#
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLKSRC_STM32=y
CONFIG_ARMV7M_SYSTICK=y
# CONFIG_MICROCHIP_PIT64B is not set
# end of Clock Source drivers

# CONFIG_MAILBOX is not set

#
# Remoteproc drivers
#
# CONFIG_REMOTEPROC is not set
# end of Remoteproc drivers

#
# Rpmsg drivers
#
# CONFIG_RPMSG_VIRTIO is not set
# end of Rpmsg drivers

# CONFIG_SOUNDWIRE is not set

#
# SOC (System On Chip) specific Drivers
#

#
# Amlogic SoC drivers
#
# end of Amlogic SoC drivers

#
# Broadcom SoC drivers
#
# CONFIG_SOC_BRCMSTB is not set
# end of Broadcom SoC drivers

#
# NXP/Freescale QorIQ SoC drivers
#
# CONFIG_QUICC_ENGINE is not set
# CONFIG_FSL_RCPM is not set
# end of NXP/Freescale QorIQ SoC drivers

#
# i.MX SoC drivers
#
# end of i.MX SoC drivers

#
# Enable LiteX SoC Builder specific drivers
#
# CONFIG_LITEX_SOC_CONTROLLER is not set
# end of Enable LiteX SoC Builder specific drivers

#
# Qualcomm SoC drivers
#
# end of Qualcomm SoC drivers

# CONFIG_SOC_TI is not set

#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers

# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_PWM is not set

#
# IRQ chip support
#
CONFIG_IRQCHIP=y
CONFIG_ARM_NVIC=y
# CONFIG_AL_FIC is not set
CONFIG_STM32_EXTI=y
# end of IRQ chip support

# CONFIG_IPACK_BUS is not set
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_RESET_CONTROLLER=y
# CONFIG_RESET_BRCMSTB_RESCAL is not set
# CONFIG_RESET_INTEL_GW is not set
CONFIG_RESET_SIMPLE=y
# CONFIG_RESET_TI_SYSCON is not set

#
# PHY Subsystem
#
# CONFIG_GENERIC_PHY is not set
# CONFIG_BCM_KONA_USB2_PHY is not set
# CONFIG_PHY_CADENCE_TORRENT is not set
# CONFIG_PHY_CADENCE_DPHY is not set
# CONFIG_PHY_CADENCE_SIERRA is not set
# CONFIG_PHY_CADENCE_SALVO is not set
# CONFIG_PHY_FSL_IMX8MQ_USB is not set
# CONFIG_PHY_MIXEL_MIPI_DPHY is not set
# CONFIG_PHY_PXA_28NM_HSIC is not set
# CONFIG_PHY_PXA_28NM_USB2 is not set
# CONFIG_PHY_OCELOT_SERDES is not set
# CONFIG_PHY_STM32_USBPHYC is not set
# end of PHY Subsystem

# CONFIG_POWERCAP is not set
# CONFIG_MCB is not set
# CONFIG_RAS is not set

#
# Android
#
# CONFIG_ANDROID is not set
# end of Android

# CONFIG_DAX is not set
# CONFIG_NVMEM is not set

#
# HW tracing support
#
# CONFIG_STM is not set
# CONFIG_INTEL_TH is not set
# end of HW tracing support

# CONFIG_FPGA is not set
# CONFIG_FSI is not set
# CONFIG_SIOX is not set
# CONFIG_SLIMBUS is not set
# CONFIG_INTERCONNECT is not set
# CONFIG_COUNTER is not set
# end of Device Drivers

#
# File systems
#
# CONFIG_VALIDATE_FS_PARSER is not set
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_EXPORTFS=y
# CONFIG_EXPORTFS_BLOCK_OPS is not set
# CONFIG_FILE_LOCKING is not set
# CONFIG_FS_ENCRYPTION is not set
# CONFIG_FS_VERITY is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_FUSE_FS is not set
# CONFIG_OVERLAY_FS is not set

#
# Caches
#
# CONFIG_NETFS_SUPPORT is not set
# CONFIG_FSCACHE is not set
# end of Caches

#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
# end of CD-ROM/DVD Filesystems

#
# DOS/FAT/EXFAT/NT Filesystems
#
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EXFAT_FS is not set
# CONFIG_NTFS_FS is not set
# end of DOS/FAT/EXFAT/NT Filesystems

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
# CONFIG_PROC_CHILDREN is not set
CONFIG_KERNFS=y
CONFIG_SYSFS=y
# CONFIG_CONFIGFS_FS is not set
# end of Pseudo filesystems

# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_MAC_ROMAN is not set
# CONFIG_NLS_MAC_CELTIC is not set
# CONFIG_NLS_MAC_CENTEURO is not set
# CONFIG_NLS_MAC_CROATIAN is not set
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
# CONFIG_NLS_MAC_GREEK is not set
# CONFIG_NLS_MAC_ICELAND is not set
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
# CONFIG_NLS_UTF8 is not set
# CONFIG_UNICODE is not set
CONFIG_IO_WQ=y
# end of File systems

#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
# CONFIG_HARDENED_USERCOPY is not set
# CONFIG_FORTIFY_SOURCE is not set
# CONFIG_STATIC_USERMODEHELPER is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,bpf"

#
# Kernel hardening options
#

#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
# end of Memory initialization
# end of Kernel hardening options
# end of Security options

CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
# CONFIG_CRYPTO_MANAGER is not set
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set

#
# Public-key cryptography
#
# CONFIG_CRYPTO_RSA is not set
# CONFIG_CRYPTO_DH is not set
# CONFIG_CRYPTO_ECDH is not set
# CONFIG_CRYPTO_ECDSA is not set
# CONFIG_CRYPTO_ECRDSA is not set
# CONFIG_CRYPTO_SM2 is not set
# CONFIG_CRYPTO_CURVE25519 is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
# CONFIG_CRYPTO_AEGIS128 is not set
# CONFIG_CRYPTO_SEQIV is not set
# CONFIG_CRYPTO_ECHAINIV is not set

#
# Block modes
#
# CONFIG_CRYPTO_CBC is not set
# CONFIG_CRYPTO_CFB is not set
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_OFB is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_KEYWRAP is not set
# CONFIG_CRYPTO_ADIANTUM is not set
# CONFIG_CRYPTO_ESSIV is not set

#
# Hash modes
#
# CONFIG_CRYPTO_CMAC is not set
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_VMAC is not set

#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRC32 is not set
# CONFIG_CRYPTO_XXHASH is not set
# CONFIG_CRYPTO_BLAKE2B is not set
# CONFIG_CRYPTO_BLAKE2S is not set
# CONFIG_CRYPTO_CRCT10DIF is not set
# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_POLY1305 is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_SHA3 is not set
# CONFIG_CRYPTO_SM3 is not set
# CONFIG_CRYPTO_STREEBOG is not set
# CONFIG_CRYPTO_WP512 is not set

#
# Ciphers
#
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_AES_TI is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_CHACHA20 is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_SM4 is not set
# CONFIG_CRYPTO_TWOFISH is not set

#
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_842 is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set
# CONFIG_CRYPTO_ZSTD is not set

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_DRBG_MENU is not set
# CONFIG_CRYPTO_JITTERENTROPY is not set

#
# Crypto library routines
#
# CONFIG_CRYPTO_LIB_BLAKE2S is not set
# CONFIG_CRYPTO_LIB_CHACHA is not set
# CONFIG_CRYPTO_LIB_CURVE25519 is not set
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
# CONFIG_CRYPTO_LIB_POLY1305 is not set
# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
# CONFIG_CRYPTO_DEV_STM32_CRC is not set
# CONFIG_CRYPTO_DEV_STM32_HASH is not set
# CONFIG_CRYPTO_DEV_STM32_CRYP is not set
# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
# CONFIG_CRYPTO_DEV_CCREE is not set
# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set

#
# Certificates for signature checking
#
# end of Certificates for signature checking

#
# Library routines
#
# CONFIG_PACKING is not set
CONFIG_BITREVERSE=y
CONFIG_HAVE_ARCH_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
# CONFIG_CORDIC is not set
# CONFIG_PRIME_NUMBERS is not set
CONFIG_RATIONAL=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
# CONFIG_CRC_CCITT is not set
CONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC4 is not set
CONFIG_CRC7=y
# CONFIG_LIBCRC32C is not set
# CONFIG_CRC8 is not set
# CONFIG_RANDOM32_SELFTEST is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_BCJ=y
# CONFIG_XZ_DEC_TEST is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_DMA=y
CONFIG_DMA_OPS=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_DMA_DECLARE_COHERENT=y
CONFIG_ARCH_HAS_SETUP_DMA_OPS=y
CONFIG_DMA_NONCOHERENT_MMAP=y
# CONFIG_DMA_API_DEBUG is not set
CONFIG_GENERIC_ATOMIC64=y
# CONFIG_IRQ_POLL is not set
CONFIG_LIBFDT=y
CONFIG_FONT_SUPPORT=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_ARCH_NO_SG_CHAIN=y
CONFIG_SBITMAP=y
# CONFIG_STRING_SELFTEST is not set
# end of Library routines

CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y

#
# Kernel hacking
#

#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
# CONFIG_PRINTK_CALLER is not set
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DYNAMIC_DEBUG_CORE is not set
CONFIG_SYMBOLIC_ERRNAME=y
# CONFIG_DEBUG_BUGVERBOSE is not set
# end of printk and dmesg options

#
# Compile-time checks and compiler options
#
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not set
# CONFIG_DEBUG_INFO_COMPRESSED is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
# CONFIG_DEBUG_INFO_BTF is not set
# CONFIG_GDB_SCRIPTS is not set
CONFIG_FRAME_WARN=1024
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_HEADERS_INSTALL is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set
# CONFIG_VMLINUX_MAP is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# end of Compile-time checks and compiler options

#
# Generic Kernel Debugging Instruments
#
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_MAGIC_SYSRQ_SERIAL=y
CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
# CONFIG_DEBUG_FS is not set
# CONFIG_UBSAN is not set
# end of Generic Kernel Debugging Instruments

CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MISC=y

#
# Memory Debugging
#
# CONFIG_PAGE_EXTENSION is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_PAGE_OWNER is not set
# CONFIG_PAGE_POISONING is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_STATS is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_SCHED_STACK_END_CHECK is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_NOMMU_REGIONS is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
# end of Memory Debugging

# CONFIG_DEBUG_SHIRQ is not set

#
# Debug Oops, Lockups and Hangs
#
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
# CONFIG_SOFTLOCKUP_DETECTOR is not set
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_WQ_WATCHDOG is not set
# end of Debug Oops, Lockups and Hangs

#
# Scheduler Debugging
#
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# end of Scheduler Debugging

# CONFIG_DEBUG_TIMEKEEPING is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_LOCK_TORTURE_TEST is not set
# CONFIG_WW_MUTEX_SELFTEST is not set
# CONFIG_SCF_TORTURE_TEST is not set
# end of Lock Debugging (spinlocks, mutexes, etc...)

# CONFIG_DEBUG_IRQFLAGS is not set
# CONFIG_STACKTRACE is not set
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
# CONFIG_DEBUG_KOBJECT is not set

#
# Debug kernel data structures
#
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_PLIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BUG_ON_DATA_CORRUPTION is not set
# end of Debug kernel data structures

# CONFIG_DEBUG_CREDENTIALS is not set

#
# RCU Debugging
#
# CONFIG_RCU_SCALE_TEST is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_REF_SCALE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
CONFIG_RCU_TRACE=y
# CONFIG_RCU_EQS_DEBUG is not set
# end of RCU Debugging

# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_LATENCYTOP is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACE_CLOCK=y
# CONFIG_SAMPLES is not set

#
# arm Debugging
#
CONFIG_UNWINDER_ARM=y
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_LL is not set
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
# CONFIG_CORESIGHT is not set
# end of arm Debugging

#
# Kernel Testing and Coverage
#
# CONFIG_KUNIT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_ARCH_HAS_KCOV=y
CONFIG_CC_HAS_SANCOV_TRACE_PC=y
# CONFIG_KCOV is not set
CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_TEST_MIN_HEAP is not set
# CONFIG_TEST_SORT is not set
# CONFIG_TEST_DIV64 is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_REED_SOLOMON_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_TEST_HEXDUMP is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_STRSCPY is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_TEST_PRINTF is not set
# CONFIG_TEST_BITMAP is not set
# CONFIG_TEST_UUID is not set
# CONFIG_TEST_XARRAY is not set
# CONFIG_TEST_OVERFLOW is not set
# CONFIG_TEST_RHASHTABLE is not set
# CONFIG_TEST_HASH is not set
# CONFIG_TEST_IDA is not set
# CONFIG_FIND_BIT_BENCHMARK is not set
# CONFIG_TEST_SYSCTL is not set
# CONFIG_TEST_UDELAY is not set
# CONFIG_TEST_MEMCAT_P is not set
# CONFIG_TEST_STACKINIT is not set
# CONFIG_TEST_MEMINIT is not set
# CONFIG_TEST_FREE_PAGES is not set
CONFIG_ARCH_USE_MEMTEST=y
# CONFIG_MEMTEST is not set
# end of Kernel Testing and Coverage
# end of Kernel hacking

[-- Attachment #3: u_boot_uimage_Toolchain_10-2020-q4-major_initcall_debug.log.txt --]
[-- Type: text/plain, Size: 28820 bytes --]


U-Boot 2021.07-rc2 (May 28 2021 - 17:05:35 +0200)                                                                              
                                                                                                                               
DRAM:  8 MiB                                                                                                                   
Flash: 2 MiB                                                                                                                   
Loading Environment from Flash... OK                                                                                           
In:    serial@40011000                                                                                                         
Out:   serial@40011000                                                                                                         
Err:   serial@40011000                                                                                                         
Hit any key to stop autoboot:  0                                                                                               
U-Boot >  setenv bootargs 'console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2 initcall_debug'
U-Boot > setenv loadaddr 0x90400000                                                                                            
U-Boot > loady                                                                                                                 
## Ready for binary (ymodem) download to 0x90400000 at 115200 bps...                                                           
C CRC mode, 156(SOH)/0(STX)/0(CAN) packets, 7 retries                                                                          
## Total Size      = 0x00004cad = 19629 Bytes                                                                                  
U-Boot > setenv loadaddr 0x90406000                                                                                            
U-Boot > loady
## Ready for binary (ymodem) download to 0x90406000 at 115200 bps...                                                           
CxyzModem - CRC mode, 12473(SOH)/0(STX)/0(CAN) packets, 5 retries
## Total Size      = 0x00185b68 = 1596264 Bytes
U-Boot > bootm 0x90406000 - 0x90400000
## Booting kernel from Legacy Image at 90406000 ...
   Image Name:   Linux-5.13.0-rc1-00082-g8743c6c7
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1596200 Bytes = 1.5 MiB
   Load Address: 90008000
   Entry Point:  90008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 90400000
   Booting using the fdt blob at 0x90400000
   Loading Kernel Image
   Loading Device Tree to 905b9000, end 905c0cac ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.13.0-rc1-00082-g8743c6c7048c (nxp11987@lmecxl0573.lme.st.com) (arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (r1
[    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: unknown data cache, unknown instruction cache
[    0.000000] OF: fdt: Machine model: STMicroelectronics STM32F429i-DISCO board
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] On node 0 totalpages: 2048
[    0.000000]   Normal zone: 16 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 2048 pages, LIFO batch:0
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
[    0.000000] Kernel command line: console=tty0 console=ttySTM0,115200 root=/dev/ram rdinit=/linuxrc loglevel=8 fbcon=rotate:2 initcall_debug
[    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 5256K/8192K available (1379K kernel code, 302K rwdata, 520K rodata, 324K init, 118K bss, 2936K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000]  Trampoline variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] /soc/interrupt-controller@40013c00: bank0
[    0.000000] random: get_random_bytes called from start_kernel+0x1ed/0x364 with crng_init=0
[    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 331816030 ns
[    0.000000] ARM System timer initialized as clocksource
[    0.000025] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
[    0.000678] timer@40000c00: STM32 sched_clock registered
[    0.001277] Switching to timer-based delay loop, resolution 11ns
[    0.001720] timer@40000c00: STM32 delay timer registered
[    0.002256] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 21236227187 ns
[    0.003066] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
[    0.014751] Console: colour dummy device 80x30
[    0.062500] printk: console [tty0] enabled
[    0.063953] Calibrating delay loop (skipped), value calculated using timer frequency.. 180.00 BogoMIPS (lpj=900000)
[    0.066518] pid_max: default: 4096 minimum: 301
[    0.071470] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.073788] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.102609] calling  cpu_suspend_alloc_sp+0x1/0x54 @ 1
[    0.104556] initcall cpu_suspend_alloc_sp+0x1/0x54 returned 0 after 0 usecs
[    0.106605] calling  spawn_ksoftirqd+0x1/0x2c @ 1
[    0.109997] initcall spawn_ksoftirqd+0x1/0x2c returned 0 after 0 usecs
[    0.112090] calling  srcu_bootup_announce+0x1/0x2c @ 1
[    0.113677] rcu: Hierarchical SRCU implementation.
[    0.115058] initcall srcu_bootup_announce+0x1/0x2c returned 0 after 9765 usecs
[    0.117216] calling  rcu_sysrq_init+0x1/0x18 @ 1
[    0.118713] initcall rcu_sysrq_init+0x1/0x18 returned 0 after 0 usecs
[    0.120535] calling  check_cpu_stall_init+0x1/0x18 @ 1
[    0.122126] initcall check_cpu_stall_init+0x1/0x18 returned 0 after 0 usecs
[    0.124037] calling  rcu_spawn_gp_kthread+0x1/0x108 @ 1
[    0.127094] initcall rcu_spawn_gp_kthread+0x1/0x108 returned 0 after 0 usecs
[    0.129028] calling  rcu_spawn_core_kthreads+0x1/0x58 @ 1
[    0.130667] initcall rcu_spawn_core_kthreads+0x1/0x58 returned 0 after 0 usecs
[    0.132829] calling  initialize_ptr_random+0x1/0x3c @ 1
[    0.134561] initcall initialize_ptr_random+0x1/0x3c returned 0 after 0 usecs
[    0.141029] devtmpfs: initialized
[    0.361184] calling  ptrace_break_init+0x1/0x24 @ 1
[    0.362919] initcall ptrace_break_init+0x1/0x24 returned 0 after 0 usecs
[    0.364971] calling  wq_sysfs_init+0x1/0x24 @ 1
[    0.369422] initcall wq_sysfs_init+0x1/0x24 returned 0 after 9765 usecs
[    0.371536] calling  ksysfs_init+0x1/0x64 @ 1
[    0.373956] initcall ksysfs_init+0x1/0x64 returned 0 after 0 usecs
[    0.376004] calling  pm_init+0x1/0x44 @ 1
[    0.380345] initcall pm_init+0x1/0x44 returned 0 after 0 usecs
[    0.382021] calling  rcu_set_runtime_mode+0x1/0x14 @ 1
[    0.383604] initcall rcu_set_runtime_mode+0x1/0x14 returned 0 after 0 usecs
[    0.385508] calling  dma_init_reserved_memory+0x1/0x38 @ 1
[    0.387164] initcall dma_init_reserved_memory+0x1/0x38 returned -12 after 0 usecs
[    0.389565] calling  init_jiffies_clocksource+0x1/0x10 @ 1
[    0.391266] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.393671] initcall init_jiffies_clocksource+0x1/0x10 returned 0 after 0 usecs
[    0.395874] calling  cpu_pm_init+0x1/0x10 @ 1
[    0.397534] initcall cpu_pm_init+0x1/0x10 returned 0 after 0 usecs
[    0.399710] calling  init_script_binfmt+0x1/0x14 @ 1
[    0.401471] initcall init_script_binfmt+0x1/0x14 returned 0 after 0 usecs
[    0.403553] calling  init_elf_fdpic_binfmt+0x1/0x14 @ 1
[    0.405360] initcall init_elf_fdpic_binfmt+0x1/0x14 returned 0 after 0 usecs
[    0.407486] calling  init_flat_binfmt+0x1/0x14 @ 1
[    0.409410] initcall init_flat_binfmt+0x1/0x14 returned 0 after 0 usecs
[    0.411461] calling  prandom_init_early+0x1/0x98 @ 1
[    0.413274] initcall prandom_init_early+0x1/0x98 returned 0 after 0 usecs
[    0.415405] calling  pinctrl_init+0x1/0x10 @ 1
[    0.417121] pinctrl core: initialized pinctrl subsystem
[    0.418376] initcall pinctrl_init+0x1/0x10 returned 0 after 0 usecs
[    0.420619] calling  gpiolib_dev_init+0x1/0xc0 @ 1
[    0.424495] initcall gpiolib_dev_init+0x1/0xc0 returned 0 after 0 usecs
[    0.429523] calling  irq_sysfs_init+0x1/0x60 @ 1
[    0.462695] initcall irq_sysfs_init+0x1/0x60 returned 0 after 29296 usecs
[    0.464558] calling  bdi_class_init+0x1/0x2c @ 1
[    0.466618] initcall bdi_class_init+0x1/0x2c returned 0 after 0 usecs
[    0.468496] calling  mm_sysfs_init+0x1/0x28 @ 1
[    0.470374] initcall mm_sysfs_init+0x1/0x28 returned 0 after 0 usecs
[    0.472235] calling  init_per_zone_wmark_min+0x1/0x4c @ 1
[    0.474034] initcall init_per_zone_wmark_min+0x1/0x4c returned 0 after 0 usecs
[    0.476321] calling  backlight_class_init+0x1/0x6c @ 1
[    0.478705] initcall backlight_class_init+0x1/0x6c returned 0 after 0 usecs
[    0.481081] calling  amba_init+0x1/0xc @ 1
[    0.483910] initcall amba_init+0x1/0xc returned 0 after 0 usecs
[    0.485905] calling  tty_class_init+0x1/0x2c @ 1
[    0.487881] initcall tty_class_init+0x1/0x2c returned 0 after 0 usecs
[    0.489669] calling  vtconsole_class_init+0x1/0xa4 @ 1
[    0.494278] initcall vtconsole_class_init+0x1/0xa4 returned 0 after 0 usecs
[    0.496174] calling  devlink_class_init+0x1/0x30 @ 1
[    0.498256] initcall devlink_class_init+0x1/0x30 returned 0 after 0 usecs
[    0.500133] calling  software_node_init+0x1/0x2c @ 1
[    0.502069] initcall software_node_init+0x1/0x2c returned 0 after 0 usecs
[    0.503972] calling  wakeup_sources_debugfs_init+0x1/0x4 @ 1
[    0.505678] initcall wakeup_sources_debugfs_init+0x1/0x4 returned 0 after 0 usecs
[    0.507908] calling  wakeup_sources_sysfs_init+0x1/0x24 @ 1
[    0.510126] initcall wakeup_sources_sysfs_init+0x1/0x24 returned 0 after 0 usecs
[    0.512538] calling  regmap_initcall+0x1/0x4 @ 1
[    0.514055] initcall regmap_initcall+0x1/0x4 returned 0 after 0 usecs
[    0.515898] calling  syscon_init+0x1/0xc @ 1
[    0.518543] initcall syscon_init+0x1/0xc returned 0 after 0 usecs
[    0.520329] calling  spi_init+0x1/0x58 @ 1
[    0.523653] initcall spi_init+0x1/0x58 returned 0 after 9765 usecs
[    0.525459] calling  i2c_init+0x1/0x80 @ 1
[    0.529142] initcall i2c_init+0x1/0x80 returned 0 after 0 usecs
[    0.533830] calling  customize_machine+0x1/0x14 @ 1
[    0.535564] initcall customize_machine+0x1/0x14 returned 0 after 0 usecs
[    0.537622] calling  exceptions_init+0x1/0x58 @ 1
[    0.539348] initcall exceptions_init+0x1/0x58 returned 0 after 0 usecs
[    0.541398] calling  kcmp_cookies_init+0x1/0x2c @ 1
[    0.543453] initcall kcmp_cookies_init+0x1/0x2c returned 0 after 0 usecs
[    0.545333] calling  stm32_exti_arch_init+0x1/0xc @ 1
[    0.548038] initcall stm32_exti_arch_init+0x1/0xc returned 0 after 0 usecs
[    0.550180] calling  stm32f429_pinctrl_init+0x1/0xc @ 1
[    0.553145] initcall stm32f429_pinctrl_init+0x1/0xc returned 0 after 9765 usecs
[    0.555566] calling  dma_bus_init+0x1/0x68 @ 1
[    0.557951] initcall dma_bus_init+0x1/0x68 returned 0 after 0 usecs
[    0.560028] calling  dma_channel_table_init+0x1/0x8c @ 1
[    0.562867] initcall dma_channel_table_init+0x1/0x8c returned 0 after 0 usecs
[    0.565292] calling  stm32_dmamux_init+0x1/0xc @ 1
[    0.567695] initcall stm32_dmamux_init+0x1/0xc returned 0 after 0 usecs
[    0.569502] calling  of_platform_default_populate_init+0x1/0x6a @ 1
[    0.832095] stm32f429-pinctrl soc:pin-controller: No package detected, use default one
[    0.853970] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
[    0.863359] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
[    0.873017] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
[    0.882444] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
[    0.891830] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
[    0.901352] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
[    0.910826] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
[    0.920351] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
[    0.930113] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
[    0.939520] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
[    0.949025] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
[    0.950870] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
[    0.981687] initcall of_platform_default_populate_init+0x1/0x6a returned 0 after 390625 usecs
[    0.987050] calling  topology_init+0x1/0x18 @ 1
[    0.991330] initcall topology_init+0x1/0x18 returned 0 after 0 usecs
[    0.993322] calling  uid_cache_init+0x1/0x80 @ 1
[    0.995161] initcall uid_cache_init+0x1/0x80 returned 0 after 0 usecs
[    0.997440] calling  param_sysfs_init+0x1/0x240 @ 1
[    1.134651] initcall param_sysfs_init+0x1/0x240 returned 0 after 126953 usecs
[    1.137500] calling  user_namespace_sysctl_init+0x1/0x28 @ 1
[    1.140638] initcall user_namespace_sysctl_init+0x1/0x28 returned 0 after 0 usecs
[    1.143123] calling  pm_sysrq_init+0x1/0x14 @ 1
[    1.146486] initcall pm_sysrq_init+0x1/0x14 returned 0 after 0 usecs
[    1.148849] calling  default_bdi_init+0x1/0x2c @ 1
[    1.154727] initcall default_bdi_init+0x1/0x2c returned 0 after 0 usecs
[    1.156641] calling  percpu_enable_async+0x1/0x10 @ 1
[    1.158817] initcall percpu_enable_async+0x1/0x10 returned 0 after 0 usecs
[    1.160776] calling  init_admin_reserve+0x1/0x24 @ 1
[    1.162455] initcall init_admin_reserve+0x1/0x24 returned 0 after 0 usecs
[    1.164458] calling  init_user_reserve+0x1/0x24 @ 1
[    1.166117] initcall init_user_reserve+0x1/0x24 returned 0 after 0 usecs
[    1.168293] calling  io_wq_init+0x1/0x30 @ 1
[    1.169932] initcall io_wq_init+0x1/0x30 returned 0 after 0 usecs
[    1.171885] calling  crc32c_mod_init+0x1/0xc @ 1
[    1.173734] initcall crc32c_mod_init+0x1/0xc returned 0 after 0 usecs
[    1.175781] calling  init_bio+0x1/0x54 @ 1
[    1.178833] initcall init_bio+0x1/0x54 returned 0 after 9765 usecs
[    1.180836] calling  blk_ioc_init+0x1/0x28 @ 1
[    1.182631] initcall blk_ioc_init+0x1/0x28 returned 0 after 0 usecs
[    1.184656] calling  blk_mq_init+0x1/0x74 @ 1
[    1.186376] initcall blk_mq_init+0x1/0x74 returned 0 after 0 usecs
[    1.188582] calling  genhd_device_init+0x1/0x50 @ 1
[    1.192787] initcall genhd_device_init+0x1/0x50 returned 0 after 0 usecs
[    1.194891] calling  stmpe_gpio_init+0x1/0xc @ 1
[    1.197606] initcall stmpe_gpio_init+0x1/0xc returned 0 after 0 usecs
[    1.200104] calling  fbmem_init+0x1/0x98 @ 1
[    1.204738] initcall fbmem_init+0x1/0x98 returned 0 after 0 usecs
[    1.206762] calling  stm32_dma_init+0x1/0xc @ 1
[    1.239296] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
[    1.271543] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
[    1.275498] initcall stm32_dma_init+0x1/0xc returned 0 after 58593 usecs
[    1.277640] calling  stm32_mdma_init+0x1/0xc @ 1
[    1.281442] initcall stm32_mdma_init+0x1/0xc returned 0 after 0 usecs
[    1.283217] calling  misc_init+0x1/0x84 @ 1
[    1.285415] initcall misc_init+0x1/0x84 returned 0 after 0 usecs
[    1.287149] calling  stmpe_init+0x1/0xc @ 1
[    1.289682] initcall stmpe_init+0x1/0xc returned 0 after 9765 usecs
[    1.291491] calling  dma_buf_init+0x1/0x34 @ 1
[    1.293919] initcall dma_buf_init+0x1/0x34 returned 0 after 0 usecs
[    1.295741] calling  input_init+0x1/0xac @ 1
[    1.298056] initcall input_init+0x1/0xac returned 0 after 0 usecs
[    1.302769] calling  iomem_init_inode+0x1/0x58 @ 1
[    1.305426] initcall iomem_init_inode+0x1/0x58 returned 0 after 0 usecs
[    1.307531] calling  clocksource_done_booting+0x1/0x30 @ 1
[    1.309292] clocksource: Switched to clocksource timer@40000c00
[    1.311169] initcall clocksource_done_booting+0x1/0x30 returned 0 after 1896 usecs
[    1.313414] calling  init_pipe_fs+0x1/0x30 @ 1
[    1.315789] initcall init_pipe_fs+0x1/0x30 returned 0 after 751 usecs
[    1.317755] calling  anon_inode_init+0x1/0x48 @ 1
[    1.320498] initcall anon_inode_init+0x1/0x48 returned 0 after 779 usecs
[    1.322556] calling  proc_nommu_init+0x1/0x24 @ 1
[    1.324351] initcall proc_nommu_init+0x1/0x24 returned 0 after 87 usecs
[    1.326405] calling  proc_cmdline_init+0x1/0x20 @ 1
[    1.328232] initcall proc_cmdline_init+0x1/0x20 returned 0 after 84 usecs
[    1.330503] calling  proc_consoles_init+0x1/0x24 @ 1
[    1.332353] initcall proc_consoles_init+0x1/0x24 returned 0 after 89 usecs
[    1.334458] calling  proc_cpuinfo_init+0x1/0x1c @ 1
[    1.336292] initcall proc_cpuinfo_init+0x1/0x1c returned 0 after 90 usecs
[    1.338381] calling  proc_devices_init+0x1/0x24 @ 1
[    1.340464] initcall proc_devices_init+0x1/0x24 returned 0 after 90 usecs
[    1.342554] calling  proc_interrupts_init+0x1/0x24 @ 1
[    1.344437] initcall proc_interrupts_init+0x1/0x24 returned 0 after 89 usecs
[    1.346572] calling  proc_loadavg_init+0x1/0x20 @ 1
[    1.348413] initcall proc_loadavg_init+0x1/0x20 returned 0 after 90 usecs
[    1.350759] calling  proc_meminfo_init+0x1/0x20 @ 1
[    1.352603] initcall proc_meminfo_init+0x1/0x20 returned 0 after 92 usecs
[    1.354700] calling  proc_stat_init+0x1/0x1c @ 1
[    1.356493] initcall proc_stat_init+0x1/0x1c returned 0 after 91 usecs
[    1.358542] calling  proc_uptime_init+0x1/0x20 @ 1
[    1.360616] initcall proc_uptime_init+0x1/0x20 returned 0 after 88 usecs
[    1.362695] calling  proc_version_init+0x1/0x20 @ 1
[    1.364547] initcall proc_version_init+0x1/0x20 returned 0 after 95 usecs
[    1.366650] calling  proc_softirqs_init+0x1/0x20 @ 1
[    1.368509] initcall proc_softirqs_init+0x1/0x20 returned 0 after 88 usecs
[    1.370877] calling  proc_kmsg_init+0x1/0x1c @ 1
[    1.372676] initcall proc_kmsg_init+0x1/0x1c returned 0 after 83 usecs
[    1.374740] calling  init_ramfs_fs+0x1/0xc @ 1
[    1.376450] initcall init_ramfs_fs+0x1/0xc returned 0 after 27 usecs
[    1.378477] calling  chr_dev_init+0x1/0x7c @ 1
[    1.617091] initcall chr_dev_init+0x1/0x7c returned 0 after 231364 usecs
[    1.618939] calling  populate_rootfs+0x1/0x38 @ 1
[    1.622201] initcall populate_rootfs+0x1/0x38 returned 0 after 93 usecs
[    1.626960] calling  proc_execdomains_init+0x1/0x20 @ 1
[    1.628890] initcall proc_execdomains_init+0x1/0x20 returned 0 after 91 usecs
[    1.688877] calling  register_warn_debugfs+0x1/0x4 @ 1
[    1.690962] initcall register_warn_debugfs+0x1/0x4 returned 0 after 5 usecs
[    1.693113] calling  ioresources_init+0x1/0x40 @ 1
[    1.695061] initcall ioresources_init+0x1/0x40 returned 0 after 170 usecs
[    1.697195] calling  irq_gc_init_ops+0x1/0x10 @ 1
[    1.698704] initcall irq_gc_init_ops+0x1/0x10 returned 0 after 12 usecs
[    1.700858] calling  irq_pm_init_ops+0x1/0x10 @ 1
[    1.702368] initcall irq_pm_init_ops+0x1/0x10 returned 0 after 12 usecs
[    1.704214] calling  timekeeping_init_ops+0x1/0x10 @ 1
[    1.705826] initcall timekeeping_init_ops+0x1/0x10 returned 0 after 12 usecs
[    1.707769] calling  init_clocksource_sysfs+0x1/0x20 @ 1
[    1.714319] initcall init_clocksource_sysfs+0x1/0x20 returned 0 after 4497 usecs
[    1.716528] calling  init_timer_list_procfs+0x1/0x30 @ 1
[    1.718262] initcall init_timer_list_procfs+0x1/0x30 returned 0 after 90 usecs
[    1.720756] calling  alarmtimer_init+0x1/0x40 @ 1
[    1.723479] initcall alarmtimer_init+0x1/0x40 returned 0 after 1160 usecs
[    1.725388] calling  init_posix_timers+0x1/0x28 @ 1
[    1.727220] initcall init_posix_timers+0x1/0x28 returned 0 after 256 usecs
[    1.729153] calling  clockevents_init_sysfs+0x1/0x44 @ 1
[    1.735627] initcall clockevents_init_sysfs+0x1/0x44 returned 0 after 4413 usecs
[    1.737845] calling  sched_clock_syscore_init+0x1/0x10 @ 1
[    1.749804] initcall sched_clock_syscore_init+0x1/0x10 returned 0 after 12 usecs
[    1.752026] calling  kallsyms_init+0x1/0x1c @ 1
[    1.753638] initcall kallsyms_init+0x1/0x1c returned 0 after 94 usecs
[    1.755501] calling  seccomp_sysctl_init+0x1/0x20 @ 1
[    1.757484] initcall seccomp_sysctl_init+0x1/0x20 returned 0 after 362 usecs
[    1.823512] calling  utsname_sysctl_init+0x1/0x10 @ 1
[    1.825643] initcall utsname_sysctl_init+0x1/0x10 returned 0 after 506 usecs
[    1.827615] calling  kswapd_init+0x1/0x10 @ 1
[    1.830777] initcall kswapd_init+0x1/0x10 returned 0 after 1630 usecs
[    1.832646] calling  workingset_init+0x1/0x68 @ 1
[    1.834223] workingset: timestamp_bits=30 max_order=11 bucket_order=0
[    1.835849] initcall workingset_init+0x1/0x68 returned 0 after 1589 usecs
[    1.837800] calling  slab_sysfs_init+0x1/0xac @ 1
[    2.099890] initcall slab_sysfs_init+0x1/0xac returned 0 after 253921 usecs
[    2.101930] calling  fcntl_init+0x1/0x28 @ 1
[    2.103785] initcall fcntl_init+0x1/0x28 returned 0 after 271 usecs
[    2.105723] calling  proc_filesystems_init+0x1/0x20 @ 1
[    2.107574] initcall proc_filesystems_init+0x1/0x20 returned 0 after 96 usecs
[    2.109977] calling  start_dirtytime_writeback+0x1/0x24 @ 1
[    2.111831] initcall start_dirtytime_writeback+0x1/0x24 returned 0 after 28 usecs
[    2.114200] calling  blkdev_init+0x1/0x10 @ 1
[    2.116326] initcall blkdev_init+0x1/0x10 returned 0 after 484 usecs
[    2.118317] calling  dio_init+0x1/0x28 @ 1
[    2.123085] initcall dio_init+0x1/0x28 returned 0 after 2806 usecs
[    2.125044] calling  io_uring_init+0x1/0x28 @ 1
[    2.126944] initcall io_uring_init+0x1/0x28 returned 0 after 229 usecs
[    2.128973] calling  crypto_algapi_init+0x1/0xc @ 1
[    2.131136] initcall crypto_algapi_init+0x1/0xc returned 0 after 91 usecs
[    2.133246] calling  proc_genhd_init+0x1/0x3c @ 1
[    2.135177] initcall proc_genhd_init+0x1/0x3c returned 0 after 181 usecs
[    2.137283] calling  deadline_init+0x1/0xc @ 1
[    2.138985] io scheduler mq-deadline registered
[    2.204145] initcall deadline_init+0x1/0xc returned 0 after 63637 usecs
[    2.206230] calling  kyber_init+0x1/0xc @ 1
[    2.207895] io scheduler kyber registered
[    2.209005] initcall kyber_init+0x1/0xc returned 0 after 1092 usecs
[    2.211339] calling  of_fixed_factor_clk_driver_init+0x1/0xc @ 1
[    2.215120] initcall of_fixed_factor_clk_driver_init+0x1/0xc returned 0 after 1730 usecs
[    2.217701] calling  of_fixed_clk_driver_init+0x1/0xc @ 1
[    2.221661] initcall of_fixed_clk_driver_init+0x1/0xc returned 0 after 1712 usecs
[    2.224135] calling  gpio_clk_driver_init+0x1/0xc @ 1
[    2.228240] initcall gpio_clk_driver_init+0x1/0xc returned 0 after 2212 usecs
[    2.230756] calling  reset_simple_driver_init+0x1/0xc @ 1
[    2.241954] initcall reset_simple_driver_init+0x1/0xc returned 0 after 9384 usecs
[    2.244115] calling  n_null_init+0x1/0x14 @ 1
[    2.245544] initcall n_null_init+0x1/0x14 returned 0 after 8 usecs
[    2.247298] calling  sysrq_init+0x1/0x30 @ 1
[    2.248958] initcall sysrq_init+0x1/0x30 returned 0 after 250 usecs
[    2.251031] calling  stm32_usart_init+0x1/0x3c @ 1
[    2.252533] STM32 USART driver initialized
[    2.318786] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 34, base_baud = 5625000) is a stm32-usart
[    2.621807] random: fast init done
[    4.771542] printk: console [ttySTM0] enabled
[    4.787938] initcall stm32_usart_init+0x1/0x3c returned 0 after 2475980 usecs
[    4.797206] calling  drm_kms_helper_init+0x1/0x4 @ 1
[    4.803784] initcall drm_kms_helper_init+0x1/0x4 returned 0 after 5 usecs
[    4.812510] calling  drm_core_init+0x1/0x6c @ 1
[    4.819058] initcall drm_core_init+0x1/0x6c returned 0 after 713 usecs
[    4.827480] calling  stm_drm_platform_driver_init+0x1/0xc @ 1
[    4.837132] initcall stm_drm_platform_driver_init+0x1/0xc returned 0 after 2110 usecs
[    4.847280] calling  ili9341_driver_init+0x1/0xc @ 1
[    4.854790] initcall ili9341_driver_init+0x1/0xc returned 0 after 902 usecs
[    4.863731] calling  topology_sysfs_init+0x1/0x28 @ 1
[    4.872183] initcall topology_sysfs_init+0x1/0x28 returned 0 after 1709 usecs
[    4.881343] calling  cacheinfo_sysfs_init+0x1/0x28 @ 1
[    4.887929] initcall cacheinfo_sysfs_init+0x1/0x28 returned -2 after 22 usecs
[    4.897093] calling  stm32_timers_driver_init+0x1/0xc @ 1
[    4.906312] initcall stm32_timers_driver_init+0x1/0xc returned 0 after 2044 usecs
[    4.916084] calling  stm32_spi_driver_init+0x1/0xc @ 1
[    4.962302] panel-ilitek-ili9341 spi0.1: get optional vcc failed
[    4.973282] spi_stm32 40015000.spi: driver initialized
[    4.985767] initcall stm32_spi_driver_init+0x1/0xc returned 0 after 61391 usecs
[    4.995342] calling  evdev_init+0x1/0xc @ 1
[    5.001419] initcall evdev_init+0x1/0xc returned 0 after 20 usecs
[    5.009129] calling  stmpe_ts_driver_init+0x1/0xc @ 1
[    5.017103] initcall stmpe_ts_driver_init+0x1/0xc returned 0 after 1224 usecs
[    5.026632] calling  i2c_dev_init+0x1/0x8c @ 1
[    5.032648] i2c /dev entries driver
[    5.037535] initcall i2c_dev_init+0x1/0x8c returned 0 after 4772 usecs
[    5.046023] calling  stm32f4_i2c_driver_init+0x1/0xc @ 1
[    5.080317] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
[    5.132138] stmpe-ts stmpe-ts: DMA mask not set
[    5.162721] input: stmpe-ts as /devices/platform/soc/40005c00.i2c/i2c-0/0-0041/stmpe-ts/input/input0
[    5.188740] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
[    5.200250] initcall stm32f4_i2c_driver_init+0x1/0xc returned 0 after 143741 usecs
[    5.212863] calling  init_machine_late+0x1/0x58 @ 1
[    5.219568] initcall init_machine_late+0x1/0x58 returned 0 after 31 usecs
[    5.228245] calling  init_oops_id+0x1/0x2c @ 1
[    5.234418] initcall init_oops_id+0x1/0x2c returned 0 after 163 usecs
[    5.242778] calling  reboot_ksysfs_init+0x1/0x38 @ 1
[    5.249955] initcall reboot_ksysfs_init+0x1/0x38 returned 0 after 298 usecs
[    5.258934] calling  printk_late_init+0x1/0xec @ 1
[    5.265323] initcall printk_late_init+0x1/0xec returned 0 after 29 usecs
[    5.273939] calling  blk_timeout_init+0x1/0x10 @ 1
[    5.280560] initcall blk_timeout_init+0x1/0x10 returned 0 after 6 usecs
[    5.289080] calling  prandom_init_late+0x1/0x1c @ 1
[    5.295825] initcall prandom_init_late+0x1/0x1c returned 0 after 10 usecs
[    5.304817] calling  amba_deferred_retry+0x1/0x60 @ 1
[    5.311556] initcall amba_deferred_retry+0x1/0x60 returned 0 after 11 usecs
[    5.320545] calling  sync_state_resume_initcall+0x1/0xa @ 1
[    5.327689] initcall sync_state_resume_initcall+0x1/0xa returned 0 after 15 usecs
[    5.337528] calling  deferred_probe_initcall+0x1/0x50 @ 1
[    5.396496] [drm] Initialized stm 1.0.0 20170330 for 40016800.display-controller on minor 0
[    6.012158] panel-ilitek-ili9341 spi0.1: initialized display rgb interface
[    6.110848] Console: switching to colour frame buffer device 30x40
[    6.378820] stm32-display 40016800.display-controller: [drm] fb0: stmdrmfb frame buffer device
[    6.523104] initcall deferred_probe_initcall+0x1/0x50 returned 0 after 1150630 usecs
[    6.634869] calling  of_fdt_raw_init+0x1/0x50 @ 1
[    6.721800] initcall of_fdt_raw_init+0x1/0x50 returned 0 after 10750 usecs
[    6.837947] calling  fb_logo_late_init+0x1/0x10 @ 1
[    6.918836] initcall fb_logo_late_init+0x1/0x10 returned 0 after 6 usecs
[    7.042600] calling  clk_disable_unused+0x1/0x76 @ 1
[    7.130445] initcall clk_disable_unused+0x1/0x76 returned 0 after 2337 usecs
[    7.258552] calling  of_platform_sync_state_init+0x1/0xa @ 1
[    7.384228] initcall of_platform_sync_state_init+0x1/0xa returned 0 after 17 usecs
[    7.551241] Freeing unused kernel memory: 324K
[    7.635490] This architecture does not have kernel memory protection.
[    7.761787] Run /linuxrc as init process
[    7.845353]   with arguments:
[    7.927244]     /linuxrc
[    7.970672]   with environment:
[    8.051435]     HOME=/
[    8.093230]     TERM=linux

[-- Attachment #4: rootfs_mcu.cpio --]
[-- Type: application/x-cpio, Size: 519168 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
  2021-05-14 11:02 ` [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue dillon.minfei
@ 2021-06-01 11:43   ` Patrice CHOTARD
  2021-06-01 11:58     ` Dillon Min
  0 siblings, 1 reply; 20+ messages in thread
From: Patrice CHOTARD @ 2021-06-01 11:43 UTC (permalink / raw)
  To: dillon.minfei, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, linux-stm32, linux-arm-kernel, linux-media

Hi Dillon

On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> From: Dillon Min <dillon.minfei@gmail.com>
> 
> As stm32f429's internal flash is 2Mbytes and compiled kernel
> image bigger than 2Mbytes, so we have to load kernel image
> to sdram on stm32f429-disco board which has 8Mbytes sdram space.
> 
> based on above context, as you knows kernel running on external
> sdram is more slower than internal flash. besides, we need read 4
> bytes to get touch screen xyz(x, y, pressure) coordinate data in
> stmpe811 interrupt.
> 
> so, in stm32f4_i2c_handle_rx_done, as i2c read slower than running
> in xip mode, have to adjust 'STOP/START bit set position' from last
> two bytes to last one bytes. else, will get i2c timeout in reading
> touch screen coordinate.
> 
> to not bring in side effect, introduce IIC_LAST_BYTE_POS to support xip
> kernel or zImage.
> 
> Fixes: 62817fc8d282 ("i2c: stm32f4: add driver")
> Link: https://lore.kernel.org/lkml/1591709203-12106-5-git-send-email-dillon.minfei@gmail.com/
> Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> ---
>  drivers/i2c/busses/i2c-stm32f4.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
> index 4933fc8ce3fd..2e41231b9037 100644
> --- a/drivers/i2c/busses/i2c-stm32f4.c
> +++ b/drivers/i2c/busses/i2c-stm32f4.c
> @@ -93,6 +93,12 @@
>  #define STM32F4_I2C_MAX_FREQ		46U
>  #define HZ_TO_MHZ			1000000
>  
> +#if !defined(CONFIG_MMU) && !defined(CONFIG_XIP_KERNEL)
> +#define IIC_LAST_BYTE_POS 1
> +#else
> +#define IIC_LAST_BYTE_POS 2
> +#endif
> +
>  /**
>   * struct stm32f4_i2c_msg - client specific data
>   * @addr: 8-bit slave addr, including r/w bit
> @@ -439,7 +445,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
>  	int i;
>  
>  	switch (msg->count) {
> -	case 2:
> +	case IIC_LAST_BYTE_POS:
>  		/*
>  		 * In order to correctly send the Stop or Repeated Start
>  		 * condition on the I2C bus, the STOP/START bit has to be set
> @@ -454,7 +460,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
>  		else
>  			stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
>  
> -		for (i = 2; i > 0; i--)
> +		for (i = IIC_LAST_BYTE_POS; i > 0; i--)
>  			stm32f4_i2c_read_msg(i2c_dev);
>  
>  		reg = i2c_dev->base + STM32F4_I2C_CR2;
> @@ -463,7 +469,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
>  
>  		complete(&i2c_dev->complete);
>  		break;
> -	case 3:
> +	case (IIC_LAST_BYTE_POS+1):
>  		/*
>  		 * In order to correctly generate the NACK pulse after the last
>  		 * received data byte, we have to enable NACK before reading N-2
> 

I tested this patch on STM32F429-Disco, it fixes the issue described by Dillon.
But i think it's not a good idea to make usage of #if !defined(CONFIG_MMU) && !defined(CONFIG_XIP_KERNEL)
inside the driver code.

Pierre-Yves, Alain, as i am not I2C expert, can you have a look at this patch and propose another solution 
to fix the original issue described by Dillon ?

Thanks
Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue
  2021-06-01 11:43   ` Patrice CHOTARD
@ 2021-06-01 11:58     ` Dillon Min
  0 siblings, 0 replies; 20+ messages in thread
From: Dillon Min @ 2021-06-01 11:58 UTC (permalink / raw)
  To: Patrice CHOTARD
  Cc: linux-clk, Stephen Boyd, Linux Kernel Mailing List,
	Michael Turquette, linux-stm32, Alexandre TORGUE,
	open list:DRM PANEL DRIVERS, linaro-mm-sig, pierre-yves.mordret,
	linux-i2c, Maxime Coquelin, alain.volmat, christian.koenig,
	Linux ARM, linux-media

Hi Patrice, Pierre-Yves, Alain

On Tue, Jun 1, 2021 at 7:43 PM Patrice CHOTARD
<patrice.chotard@foss.st.com> wrote:
>
> Hi Dillon
>
> On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> > From: Dillon Min <dillon.minfei@gmail.com>
> >
> > As stm32f429's internal flash is 2Mbytes and compiled kernel
> > image bigger than 2Mbytes, so we have to load kernel image
> > to sdram on stm32f429-disco board which has 8Mbytes sdram space.
> >
> > based on above context, as you knows kernel running on external
> > sdram is more slower than internal flash. besides, we need read 4
> > bytes to get touch screen xyz(x, y, pressure) coordinate data in
> > stmpe811 interrupt.
> >
> > so, in stm32f4_i2c_handle_rx_done, as i2c read slower than running
> > in xip mode, have to adjust 'STOP/START bit set position' from last
> > two bytes to last one bytes. else, will get i2c timeout in reading
> > touch screen coordinate.
> >
> > to not bring in side effect, introduce IIC_LAST_BYTE_POS to support xip
> > kernel or zImage.
> >
> > Fixes: 62817fc8d282 ("i2c: stm32f4: add driver")
> > Link: https://lore.kernel.org/lkml/1591709203-12106-5-git-send-email-dillon.minfei@gmail.com/
> > Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> > ---
> >  drivers/i2c/busses/i2c-stm32f4.c | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
> > index 4933fc8ce3fd..2e41231b9037 100644
> > --- a/drivers/i2c/busses/i2c-stm32f4.c
> > +++ b/drivers/i2c/busses/i2c-stm32f4.c
> > @@ -93,6 +93,12 @@
> >  #define STM32F4_I2C_MAX_FREQ         46U
> >  #define HZ_TO_MHZ                    1000000
> >
> > +#if !defined(CONFIG_MMU) && !defined(CONFIG_XIP_KERNEL)
> > +#define IIC_LAST_BYTE_POS 1
> > +#else
> > +#define IIC_LAST_BYTE_POS 2
> > +#endif
> > +
> >  /**
> >   * struct stm32f4_i2c_msg - client specific data
> >   * @addr: 8-bit slave addr, including r/w bit
> > @@ -439,7 +445,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
> >       int i;
> >
> >       switch (msg->count) {
> > -     case 2:
> > +     case IIC_LAST_BYTE_POS:
> >               /*
> >                * In order to correctly send the Stop or Repeated Start
> >                * condition on the I2C bus, the STOP/START bit has to be set
> > @@ -454,7 +460,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
> >               else
> >                       stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
> >
> > -             for (i = 2; i > 0; i--)
> > +             for (i = IIC_LAST_BYTE_POS; i > 0; i--)
> >                       stm32f4_i2c_read_msg(i2c_dev);
> >
> >               reg = i2c_dev->base + STM32F4_I2C_CR2;
> > @@ -463,7 +469,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
> >
> >               complete(&i2c_dev->complete);
> >               break;
> > -     case 3:
> > +     case (IIC_LAST_BYTE_POS+1):
> >               /*
> >                * In order to correctly generate the NACK pulse after the last
> >                * received data byte, we have to enable NACK before reading N-2
> >
>
> I tested this patch on STM32F429-Disco, it fixes the issue described by Dillon.
> But i think it's not a good idea to make usage of #if !defined(CONFIG_MMU) && !defined(CONFIG_XIP_KERNEL)
> inside the driver code.

Hi Patrice,
Thanks for your time.

How about introducing a dts node for this purpose.
like
stm32-i2c,last-byte-pos = <1>;
or
stm32-i2c,last-byte-pos = <2>;

if not set, the default value is 2

Best Regards
Dillon

>
> Pierre-Yves, Alain, as i am not I2C expert, can you have a look at this patch and propose another solution
> to fix the original issue described by Dillon ?
>
> Thanks
> Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/4] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate
  2021-05-14 11:02 ` [PATCH 3/4] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate dillon.minfei
@ 2021-06-01 12:48   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2021-06-01 12:48 UTC (permalink / raw)
  To: dillon.minfei, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, linux-stm32, linux-arm-kernel, linux-media

Hi Dillon

On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> From: Dillon Min <dillon.minfei@gmail.com>
> 
> This is due to misuse ‘PLL_VCO_SAI' and'PLL_SAI' in clk-stm32f4.c
> 'PLL_SAI' is 2, 'PLL_VCO_SAI' is 7(defined in
> include/dt-bindings/clock/stm32fx-clock.h).
> 
> 'post_div' point to 'post_div_data[]', 'post_div->pll_num'
> is PLL_I2S or PLL_SAI.
> 
> 'clks[PLL_VCO_SAI]' has valid 'struct clk_hw* ' return
> from stm32f4_rcc_register_pll() but, at line 1777 of
> driver/clk/clk-stm32f4.c, use the 'clks[post_div->pll_num]',
> equal to 'clks[PLL_SAI]', this is invalid array member at that time.
> 
> Fixes: 517633ef630e ("clk: stm32f4: Add post divisor for I2S & SAI PLLs")
> Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> Acked-by: Stephen Boyd <sboyd@kernel.org>
> Link: https://lore.kernel.org/linux-arm-kernel/1590564453-24499-6-git-send-email-dillon.minfei@gmail.com/
> ---
>  drivers/clk/clk-stm32f4.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
> index 18117ce5ff85..42ca2dd86aea 100644
> --- a/drivers/clk/clk-stm32f4.c
> +++ b/drivers/clk/clk-stm32f4.c
> @@ -557,13 +557,13 @@ static const struct clk_div_table post_divr_table[] = {
>  
>  #define MAX_POST_DIV 3
>  static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
> -	{ CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
> +	{ CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
>  		CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
>  
> -	{ CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
> +	{ CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
>  		CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
>  
> -	{ NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
> +	{ NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
>  		STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
>  };
>  
> 
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/4] clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after kernel startup
  2021-05-14 11:02 ` [PATCH 4/4] clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after kernel startup dillon.minfei
@ 2021-06-01 12:51   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2021-06-01 12:51 UTC (permalink / raw)
  To: dillon.minfei, pierre-yves.mordret, alain.volmat,
	mcoquelin.stm32, alexandre.torgue, sumit.semwal,
	christian.koenig, mturquette
  Cc: sboyd, linux-kernel, dri-devel, linux-clk, linaro-mm-sig,
	linux-i2c, linux-stm32, linux-arm-kernel, linux-media

Hi Dillon

On 5/14/21 1:02 PM, dillon.minfei@gmail.com wrote:
> From: Dillon Min <dillon.minfei@gmail.com>
> 
> stm32's clk driver register two ltdc gate clk to clk core by
> clk_hw_register_gate() and clk_hw_register_composite()
> 
> first: 'stm32f429_gates[]', clk name is 'ltdc', which no user to use.
> second: 'stm32f429_aux_clk[]', clk name is 'lcd-tft', used by ltdc driver
> 
> both of them point to the same offset of stm32's RCC register. after
> kernel enter console, clk core turn off ltdc's clk as 'stm32f429_gates[]'
> is no one to use. but, actually 'stm32f429_aux_clk[]' is in use.
> 
> Fixes: daf2d117cbca ("clk: stm32f4: Add lcd-tft clock")
> Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
> Acked-by: Stephen Boyd <sboyd@kernel.org>
> Link: https://lore.kernel.org/linux-arm-kernel/1590564453-24499-7-git-send-email-dillon.minfei@gmail.com/
> ---
>  drivers/clk/clk-stm32f4.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
> index 42ca2dd86aea..f4156a8a6041 100644
> --- a/drivers/clk/clk-stm32f4.c
> +++ b/drivers/clk/clk-stm32f4.c
> @@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = {
>  	{ STM32F4_RCC_APB2ENR, 20,	"spi5",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
> -	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
>  };
>  
>  static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
> @@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
>  	{ STM32F4_RCC_APB2ENR, 20,	"spi5",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
> -	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
>  };
>  
>  static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
> @@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
>  	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 23,	"sai2",		"apb2_div" },
> -	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
>  };
>  
>  static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
> @@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
>  	{ STM32F4_RCC_APB2ENR, 21,	"spi6",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 22,	"sai1",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 23,	"sai2",		"apb2_div" },
> -	{ STM32F4_RCC_APB2ENR, 26,	"ltdc",		"apb2_div" },
>  	{ STM32F4_RCC_APB2ENR, 30,	"mdio",		"apb2_div" },
>  };
>  
> 

Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2021-06-01 12:51 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-14 11:02 [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform dillon.minfei
2021-05-14 11:02 ` [PATCH 1/4] drm/panel: Add ilitek ili9341 panel driver dillon.minfei
2021-05-31 13:15   ` Patrice CHOTARD
2021-05-31 13:39     ` Dillon Min
2021-06-01  2:31       ` Dillon Min
2021-05-14 11:02 ` [PATCH 2/4] i2c: stm32f4: Fix stmpe811 get xyz data timeout issue dillon.minfei
2021-06-01 11:43   ` Patrice CHOTARD
2021-06-01 11:58     ` Dillon Min
2021-05-14 11:02 ` [PATCH 3/4] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate dillon.minfei
2021-06-01 12:48   ` Patrice CHOTARD
2021-05-14 11:02 ` [PATCH 4/4] clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after kernel startup dillon.minfei
2021-06-01 12:51   ` Patrice CHOTARD
2021-05-28  6:01 ` [PATCH 0/4] Fix the i2c/clk bug of stm32 mcu platform Dillon Min
2021-05-31 13:20 ` Patrice CHOTARD
2021-05-31 13:38   ` Dillon Min
2021-05-31 13:50     ` Patrice CHOTARD
2021-05-31 14:29       ` Dillon Min
2021-05-31 14:58         ` Patrice CHOTARD
2021-06-01  3:28           ` Dillon Min
2021-06-01  8:00             ` Patrice CHOTARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).