[PATCH 2/2] drm/bridge: Add IT6151 bridge driver

2015-03-11 Thread CK Hu
This patch adds a drm_bridge driver for the IT6151 MIPI to eDP
bridge chip.

Signed-off-by: CK Hu ck...@mediatek.com
Signed-off-by: Jitao Shi jitao@mediatek.com
---
 drivers/gpu/drm/bridge/Kconfig  |  10 +
 drivers/gpu/drm/bridge/Makefile |   1 +
 drivers/gpu/drm/bridge/it6151.c | 601 
 include/drm/bridge/it6151.h |  34 +++
 4 files changed, 646 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/it6151.c
 create mode 100644 include/drm/bridge/it6151.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index f38bbcd..2b3a78e 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -11,3 +11,13 @@ config DRM_PTN3460
select DRM_PANEL
---help---
  ptn3460 eDP-LVDS bridge chip driver.
+
+config DRM_IT6151
+   bool Enable IT6151FN : MIPI to eDP Converter
+   depends on DRM
+   select DRM_KMS_HELPER
+   help
+ Choose this option if you have IT6151 for display
+ The IT6151 is a high-performance and low-power
+ MIPI to eDP converter
+
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index d8a8cfd..98edb74 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -2,3 +2,4 @@ ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_IT6151) += it6151.o
diff --git a/drivers/gpu/drm/bridge/it6151.c b/drivers/gpu/drm/bridge/it6151.c
new file mode 100644
index 000..039fe4b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/it6151.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/module.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/i2c.h
+#include linux/gpio.h
+#include linux/delay.h
+#include linux/regulator/consumer.h
+
+#include drm/drmP.h
+#include drm/drm_crtc_helper.h
+#include drm/drm_crtc.h
+#include drm/drm_mipi_dsi.h
+#include drm/drm_panel.h
+
+
+
+#define MIPI_RX_SW_RST0x05
+#define MIPI_RX_INT_MASK  0x09
+#define MIPI_RX_SYS_CFG   0x0c
+#define MIPI_RX_MCLK  0x11
+#define MIPI_RX_PHY_IF_1  0x19
+#define MIPI_RX_PKT_DEC   0x27
+#define MIPI_RX_UFO_BLK_HIGH  0x28
+#define MIPI_RX_UFO_BLK_LOW   0x29
+#define MIPI_RX_UFO_HDE_DELAY 0x2e
+#define MIPI_RX_UFO_RESYNC0x2f
+#define MIPI_RX_RESYNC_POL0x4e
+#define MIPI_RX_PCLK_HSCLK0x80
+#define MIPI_RX_AMP_TERM  0x84
+#define MIPI_RX_TIMER_INT_CNT 0x92
+
+#define DP_TX_VEN_ID_LOW0x00
+#define DP_TX_VEN_ID_HIGH   0x01
+#define DP_TX_DEV_ID_LOW0x02
+#define DP_TX_DEV_ID_HIGH   0x03
+#define DP_TX_REV_ID0x04
+#define DP_TX_SW_RST0x05
+#define DP_TX_INT_STA_0 0x06
+#define DP_TX_INT_STA_1 0x07
+#define DP_TX_INT_STA_2 0x08
+#define DP_TX_INT_MASK_00x09
+#define DP_TX_INT_MASK_10x0a
+#define DP_TX_INT_MASK_20x0b
+#define DP_TX_SYS_CFG   0x0c
+#define DP_TX_SYS_DBG   0x0f
+#define DP_TX_LANE  0x16
+#define DP_TX_TRAIN 0x17
+#define DP_TX_AUX_CH_FIFO   0x21
+#define DP_TX_AUX_CLK   0x22
+#define DP_TX_PC_REQ_FIFO   0x23
+#define DP_TX_PC_REQ_OFST_0 0x24
+#define DP_TX_PC_REQ_OFST_1 0x25
+#define DP_TX_PC_REQ_OFST_2 0x26
+#define DP_TX_PC_REQ_WD_0   0x27
+#define DP_TX_PC_REQ_SEL0x2b
+#define DP_TX_HDP   0x3a
+#define DP_TX_LNPWDB0x5c
+#define DP_TX_EQ0x5f
+#define DP_TX_COL_CONV_19   0x76
+#define DP_TX_COL_CONV_20   0x77
+#define DP_TX_PG_H_DE_END_L 0x7e
+#define DP_TX_PG_H_DE_END_H 0x7f
+#define DP_TX_PG_H_SYNC_START_L 0x80
+#define DP_TX_PG_H_SYNC_START_H 0x81
+#define DP_TX_PG_H_SYNC_END_L   0x82
+#define DP_TX_PG_H_SYNC_END_H   0x83
+#define DP_TX_PG_V_DE_END_L 0x88
+#define DP_TX_PG_V_DE_END_H 0x89
+#define DP_TX_PG_V_DE_START_L   0x8a
+#define DP_TX_IN_VDO_TM_15  0xb5
+#define DP_TX_IN_VDO_TM_17  0xb7
+#define DP_TX_PSR_CTRL_00xc4
+#define DP_TX_PSR_CTRL_10xc5
+#define DP_TX_HDP_IRQ_TM0xc9
+#define DP_TX_AUX_DBG   0xca
+#define DP_TX_AUX_MASTER0xcb
+#define DP_TX_PKT_OPT   0xce
+#define DP_TX_VDO_FIFO  0xd3
+#define DP_TX_VDO_STMP  0xd4
+#define DP_TX_PKT   0xe8
+#define DP_TX_PKT_AVI_VIC   0xec
+#define DP_TX_MIPI_PORT 0xfd
+
+enum {
+   MIPI_1_LANE

[PATCH 2/2] drm/bridge: Add IT6151 bridge driver

2015-03-10 Thread CK Hu
This patch adds a drm_bridge driver for the IT6151 MIPI to eDP
bridge chip.

Signed-off-by: CK Hu ck...@mediatek.com
Signed-off-by: Jitao Shi jitao@mediatek.com
---
 drivers/gpu/drm/bridge/Kconfig  |  10 +
 drivers/gpu/drm/bridge/Makefile |   1 +
 drivers/gpu/drm/bridge/it6151.c | 601 
 include/drm/bridge/it6151.h |  34 +++
 4 files changed, 646 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/it6151.c
 create mode 100644 include/drm/bridge/it6151.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index f38bbcd..2b3a78e 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -11,3 +11,13 @@ config DRM_PTN3460
select DRM_PANEL
---help---
  ptn3460 eDP-LVDS bridge chip driver.
+
+config DRM_IT6151
+   bool Enable IT6151FN : MIPI to eDP Converter
+   depends on DRM
+   select DRM_KMS_HELPER
+   help
+ Choose this option if you have IT6151 for display
+ The IT6151 is a high-performance and low-power
+ MIPI to eDP converter
+
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index d8a8cfd..98edb74 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -2,3 +2,4 @@ ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_IT6151) += it6151.o
diff --git a/drivers/gpu/drm/bridge/it6151.c b/drivers/gpu/drm/bridge/it6151.c
new file mode 100644
index 000..039fe4b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/it6151.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/module.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/i2c.h
+#include linux/gpio.h
+#include linux/delay.h
+#include linux/regulator/consumer.h
+
+#include drm/drmP.h
+#include drm/drm_crtc_helper.h
+#include drm/drm_crtc.h
+#include drm/drm_mipi_dsi.h
+#include drm/drm_panel.h
+
+
+
+#define MIPI_RX_SW_RST0x05
+#define MIPI_RX_INT_MASK  0x09
+#define MIPI_RX_SYS_CFG   0x0c
+#define MIPI_RX_MCLK  0x11
+#define MIPI_RX_PHY_IF_1  0x19
+#define MIPI_RX_PKT_DEC   0x27
+#define MIPI_RX_UFO_BLK_HIGH  0x28
+#define MIPI_RX_UFO_BLK_LOW   0x29
+#define MIPI_RX_UFO_HDE_DELAY 0x2e
+#define MIPI_RX_UFO_RESYNC0x2f
+#define MIPI_RX_RESYNC_POL0x4e
+#define MIPI_RX_PCLK_HSCLK0x80
+#define MIPI_RX_AMP_TERM  0x84
+#define MIPI_RX_TIMER_INT_CNT 0x92
+
+#define DP_TX_VEN_ID_LOW0x00
+#define DP_TX_VEN_ID_HIGH   0x01
+#define DP_TX_DEV_ID_LOW0x02
+#define DP_TX_DEV_ID_HIGH   0x03
+#define DP_TX_REV_ID0x04
+#define DP_TX_SW_RST0x05
+#define DP_TX_INT_STA_0 0x06
+#define DP_TX_INT_STA_1 0x07
+#define DP_TX_INT_STA_2 0x08
+#define DP_TX_INT_MASK_00x09
+#define DP_TX_INT_MASK_10x0a
+#define DP_TX_INT_MASK_20x0b
+#define DP_TX_SYS_CFG   0x0c
+#define DP_TX_SYS_DBG   0x0f
+#define DP_TX_LANE  0x16
+#define DP_TX_TRAIN 0x17
+#define DP_TX_AUX_CH_FIFO   0x21
+#define DP_TX_AUX_CLK   0x22
+#define DP_TX_PC_REQ_FIFO   0x23
+#define DP_TX_PC_REQ_OFST_0 0x24
+#define DP_TX_PC_REQ_OFST_1 0x25
+#define DP_TX_PC_REQ_OFST_2 0x26
+#define DP_TX_PC_REQ_WD_0   0x27
+#define DP_TX_PC_REQ_SEL0x2b
+#define DP_TX_HDP   0x3a
+#define DP_TX_LNPWDB0x5c
+#define DP_TX_EQ0x5f
+#define DP_TX_COL_CONV_19   0x76
+#define DP_TX_COL_CONV_20   0x77
+#define DP_TX_PG_H_DE_END_L 0x7e
+#define DP_TX_PG_H_DE_END_H 0x7f
+#define DP_TX_PG_H_SYNC_START_L 0x80
+#define DP_TX_PG_H_SYNC_START_H 0x81
+#define DP_TX_PG_H_SYNC_END_L   0x82
+#define DP_TX_PG_H_SYNC_END_H   0x83
+#define DP_TX_PG_V_DE_END_L 0x88
+#define DP_TX_PG_V_DE_END_H 0x89
+#define DP_TX_PG_V_DE_START_L   0x8a
+#define DP_TX_IN_VDO_TM_15  0xb5
+#define DP_TX_IN_VDO_TM_17  0xb7
+#define DP_TX_PSR_CTRL_00xc4
+#define DP_TX_PSR_CTRL_10xc5
+#define DP_TX_HDP_IRQ_TM0xc9
+#define DP_TX_AUX_DBG   0xca
+#define DP_TX_AUX_MASTER0xcb
+#define DP_TX_PKT_OPT   0xce
+#define DP_TX_VDO_FIFO  0xd3
+#define DP_TX_VDO_STMP  0xd4
+#define DP_TX_PKT   0xe8
+#define DP_TX_PKT_AVI_VIC   0xec
+#define DP_TX_MIPI_PORT 0xfd
+
+enum {
+   MIPI_1_LANE

[PATCH 1/2] dt-bindings: drm/bridge: Add IT6151 bridge chip driver bindings.

2015-03-10 Thread CK Hu
Add devicetree bindings for IT6151 MIPI to eDP bridge chip driver.
---
 Documentation/devicetree/bindings/drm/bridge/it6151.txt | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/it6151.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/it6151.txt 
b/Documentation/devicetree/bindings/drm/bridge/it6151.txt
new file mode 100644
index 000..ad0ad60
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/it6151.txt
@@ -0,0 +1,15 @@
+it6151 bridge bindings
+
+Required properties:
+   - compatible: ite,it6151
+   - reg: i2c address of the bridge's dp tx.
+   - rxreg: i2c address of the bridge's mipi rx.
+   - reset-gpio: OF device-tree gpio specification
+
+Example:
+   ite6151: edp-bridge@5c {
+   compatible = ite,it6151;
+   reg = 0x5c;
+   rxreg = 0x6c;
+   reset-gpio = pio 94 GPIO_ACTIVE_HIGH;
+   };
-- 
1.8.1.1.dirty

* Email Confidentiality Notice 
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] dt-bindings: drm/bridge: Add IT6151 bridge chip driver bindings.

2015-03-11 Thread CK Hu
Add devicetree bindings for IT6151 MIPI to eDP bridge chip driver.

Signed-off-by: CK Hu ck...@mediatek.com
Signed-off-by: Jitao Shi jitao@mediatek.com
---
 Documentation/devicetree/bindings/drm/bridge/it6151.txt | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/it6151.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/it6151.txt 
b/Documentation/devicetree/bindings/drm/bridge/it6151.txt
new file mode 100644
index 000..ad0ad60
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/it6151.txt
@@ -0,0 +1,15 @@
+it6151 bridge bindings
+
+Required properties:
+   - compatible: ite,it6151
+   - reg: i2c address of the bridge's dp tx.
+   - rxreg: i2c address of the bridge's mipi rx.
+   - reset-gpio: OF device-tree gpio specification
+
+Example:
+   ite6151: edp-bridge@5c {
+   compatible = ite,it6151;
+   reg = 0x5c;
+   rxreg = 0x6c;
+   reset-gpio = pio 94 GPIO_ACTIVE_HIGH;
+   };
-- 
1.8.1.1.dirty

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC][PATCH 1/2] dt-bindings: drm/mediatek: Add Mediatek DRM dts binding

2015-05-13 Thread CK Hu
This patch includes
1. Mediatek DRM Device binding
2. Mediatek DSI Device binding
3. Mediatek CRTC Main Device binding
4. Mediatek DDP Device binding

Signed-off-by: CK Hu ck...@mediatek.com
---
 .../bindings/drm/mediatek/mediatek,crtc-main.txt   | 38 ++
 .../bindings/drm/mediatek/mediatek,ddp.txt | 22 +
 .../bindings/drm/mediatek/mediatek,drm.txt | 27 +++
 .../bindings/drm/mediatek/mediatek,dsi.txt | 20 
 4 files changed, 107 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt

diff --git 
a/Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt 
b/Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
new file mode 100644
index 000..5c6c420
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
@@ -0,0 +1,38 @@
+Mediatek CRTC Main Device
+
+
+The Mediatek CRTC Main device is a crtc device of DRM system.
+
+Required properties:
+- compatible: mediatek,chip-crtc-main
+- interrupts: The interrupt signal from the CRTC Main block.
+- reg: Physical base address and length of the controller's registers
+- clocks: device clocks
+  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
+- ddp: phandle of ddp device which control display data path.
+
+Example:
+
+crtc_main: crtc@1400c000 {
+   compatible = mediatek,mt8173-crtc-main;
+   interrupts = GIC_SPI 196 IRQ_TYPE_LEVEL_LOW;
+   reg = 0 0x1400c000 0 0x1000,  /* OVL0 */
+ 0 0x1400e000 0 0x1000,  /* RDMA0 */
+ 0 0x14013000 0 0x1000,  /* COLOR0 */
+ 0 0x14015000 0 0x1000,  /* AAL */
+ 0 0x1401a000 0 0x1000,  /* UFOE */
+ 0 0x14023000 0 0x1000;  /* OD */
+   clocks = mmsys MM_DISP_OVL0,
+mmsys MM_DISP_RDMA0,
+mmsys MM_DISP_COLOR0,
+mmsys MM_DISP_AAL,
+mmsys MM_DISP_UFOE,
+mmsys MM_DISP_OD;
+   clock-names = ovl0_disp,
+ rdma0_disp,
+ color0_disp,
+ aal_disp,
+ ufoe_disp,
+ od_disp;
+   ddp = ddp;
+};
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt 
b/Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
new file mode 100644
index 000..77cf630
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
@@ -0,0 +1,22 @@
+Mediatek DDP Device
+
+
+The Mediatek DDP device control the display data path.
+
+Required properties:
+- compatible: mediatek,chip-ddp
+- reg: Physical base address and length of the controller's registers
+- power-domains: a phandle to DDP power domain node.
+- clocks: device clocks
+  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
+
+Example:
+
+ddp: ddp@1400 {
+   compatible = mediatek,mt8173-ddp;
+   reg = 0 0x1400 0 0x100,   /* CONFIG */
+ 0 0x1402 0 0x1000;  /* MUTEX */
+   power-domains = scpsys MT8173_POWER_DOMAIN_DIS;
+   clocks = mmsys MM_MUTEX_32K;
+   clock-names = mutex_disp;
+};
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt 
b/Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
new file mode 100644
index 000..c4a5702
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
@@ -0,0 +1,27 @@
+Mediatek DRM Device
+
+
+The Mediatek DRM device is a device needed to list all
+display component nodes that comprise the display subsystem.
+And it list the memory-related interface.
+
+Required properties:
+- compatible: mediatek,chip-drm
+- larb: Should contain a list of phandles pointing to larb device.
+  larb definitions as defined in
+  Documentation/devicetree/bindings/soc/mediatek/mediatek,smi-larb.txt
+- iommus: required a iommu node
+- connectors: Should contain a list of phandles pointing to connector device.
+  connector device should be one component of this master.
+- crtcs: Should contain a list of phandles pointing to crtc device.
+  crtc device should be one component of this master.
+
+Example:
+
+drm0: drm {
+   compatible = mediatek,mt8173-drm;
+   larb = larb0;
+   iommus = iommu M4U_PORT_DISP_OVL0;
+   connectors = dsi;
+   crtcs = crtc_main;
+};
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt 
b/Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt

[RFC][PATCH 2/2] drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.

2015-05-13 Thread CK Hu
This patch is a DRM Driver for Mediatek SoC MT8173.
Now support one crtc with MIPI DSI interface.
We used GEM framework for buffer management and use iommu for
physically non-continuous memory.

Signed-off-by: CK Hu ck...@mediatek.com
---
 drivers/gpu/drm/Kconfig   |2 +
 drivers/gpu/drm/Makefile  |1 +
 drivers/gpu/drm/mediatek/Kconfig  |   28 +
 drivers/gpu/drm/mediatek/Makefile |   13 +
 drivers/gpu/drm/mediatek/mediatek_drm_crtc.c  |  246 
 drivers/gpu/drm/mediatek/mediatek_drm_crtc.h  |   80 ++
 drivers/gpu/drm/mediatek/mediatek_drm_crtc_main.c |  420 +++
 drivers/gpu/drm/mediatek/mediatek_drm_ddp.c   |  202 
 drivers/gpu/drm/mediatek/mediatek_drm_ddp.h   |   23 +
 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.c  |  346 ++
 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.h  |   33 +
 drivers/gpu/drm/mediatek/mediatek_drm_drv.c   |  369 ++
 drivers/gpu/drm/mediatek/mediatek_drm_drv.h   |   37 +
 drivers/gpu/drm/mediatek/mediatek_drm_dsi.c   | 1333 +
 drivers/gpu/drm/mediatek/mediatek_drm_dsi.h   |   71 ++
 drivers/gpu/drm/mediatek/mediatek_drm_fb.c|  339 ++
 drivers/gpu/drm/mediatek/mediatek_drm_fb.h|   43 +
 drivers/gpu/drm/mediatek/mediatek_drm_gem.c   |  315 +
 drivers/gpu/drm/mediatek/mediatek_drm_gem.h   |   94 ++
 include/uapi/drm/mediatek_drm.h   |   59 +
 20 files changed, 4054 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/Kconfig
 create mode 100644 drivers/gpu/drm/mediatek/Makefile
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_crtc.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_crtc.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_crtc_main.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_drv.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_drv.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_dsi.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_dsi.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_fb.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_fb.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_gem.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_gem.h
 create mode 100644 include/uapi/drm/mediatek_drm.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 47f2ce8..441be2d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -217,3 +217,5 @@ source drivers/gpu/drm/sti/Kconfig
 source drivers/gpu/drm/amd/amdkfd/Kconfig
 
 source drivers/gpu/drm/imx/Kconfig
+
+source drivers/gpu/drm/mediatek/Kconfig
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7d4944e..55fe66c 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_DRM_MSM) += msm/
 obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_STI) += sti/
 obj-$(CONFIG_DRM_IMX) += imx/
+obj-$(CONFIG_DRM_MEDIATEK) += mediatek/
 obj-y  += i2c/
 obj-y  += panel/
 obj-y  += bridge/
diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
new file mode 100644
index 000..fa581fb
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -0,0 +1,28 @@
+config DRM_MEDIATEK
+   tristate DRM Support for Mediatek SoCs
+   depends on DRM
+   depends on ARCH_MEDIATEK || (ARM  COMPILE_TEST)
+   select MTK_SMI
+   select DRM_PANEL
+   select DRM_MIPI_DSI
+   select DRM_PANEL_SIMPLE
+   select DRM_KMS_HELPER
+   select IOMMU_DMA
+   help
+ Choose this option if you have a Mediatek SoCs.
+ The module will be called mediatek-drm
+ This driver provides kernel mode setting and
+ buffer management to userspace.
+
+config DRM_MEDIATEK_FBDEV
+   bool Enable legacy fbdev support for Mediatek DRM
+   depends on DRM_MEDIATEK
+   select FB_SYS_FILLRECT
+   select FB_SYS_COPYAREA
+   select FB_SYS_IMAGEBLIT
+   select DRM_KMS_FB_HELPER
+   help
+ Choose this option if you have a need for the legacy
+ fbdev support.  Note that this support also provides
+ the Linux console on top of the Mediatek DRM mode
+ setting driver.
diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
new file mode 100644
index 000..a566a83
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -0,0 +1,13 @@
+mediatek-drm-objs := mediatek_drm_drv.o \
+  mediatek_drm_crtc.o \
+  mediatek_drm_fb.o \
+  mediatek_drm_gem.o

[RFC][PATCH 0/2] MT8173 DRM support

2015-05-13 Thread CK Hu
MT8173 DRM include one master drm device and three sub device: dsi device,
crtc main device, and ddp device.

Master drm device control the drm sub device and memory management.
dsi device is a drm connector/encoder device which control MIPI/DSI hw block.
crtc main is a drm crtc device which control hw components in the display data
path.
ddp is a device which control display data path.

Display data path of crtc main is:
[OVL0] - [COLOR0] - [AAL] - [OD] - [UFOE] - [RDMA0]

This patch depends on the other patches:
1. MT8173 IOMMU support

http://lists.infradead.org/pipermail/linux-mediatek/2015-March/58.html
2. add IOMMU dma_ops
cherry picked from git://linux-arm.org/linux-rm iommu/dma
commit d76a1911b02185bdc5f8b5525f9228cf266725c5

CK Hu (2):
  dt-bindings: drm/mediatek: Add Mediatek DRM dts binding
  drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.

 .../bindings/drm/mediatek/mediatek,crtc-main.txt   |   38 +
 .../bindings/drm/mediatek/mediatek,ddp.txt |   22 +
 .../bindings/drm/mediatek/mediatek,drm.txt |   27 +
 .../bindings/drm/mediatek/mediatek,dsi.txt |   20 +
 drivers/gpu/drm/Kconfig|2 +
 drivers/gpu/drm/Makefile   |1 +
 drivers/gpu/drm/mediatek/Kconfig   |   28 +
 drivers/gpu/drm/mediatek/Makefile  |   13 +
 drivers/gpu/drm/mediatek/mediatek_drm_crtc.c   |  246 
 drivers/gpu/drm/mediatek/mediatek_drm_crtc.h   |   80 ++
 drivers/gpu/drm/mediatek/mediatek_drm_crtc_main.c  |  420 ++
 drivers/gpu/drm/mediatek/mediatek_drm_ddp.c|  202 +++
 drivers/gpu/drm/mediatek/mediatek_drm_ddp.h|   23 +
 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.c   |  346 +
 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.h   |   33 +
 drivers/gpu/drm/mediatek/mediatek_drm_drv.c|  369 ++
 drivers/gpu/drm/mediatek/mediatek_drm_drv.h|   37 +
 drivers/gpu/drm/mediatek/mediatek_drm_dsi.c| 1333 
 drivers/gpu/drm/mediatek/mediatek_drm_dsi.h|   71 ++
 drivers/gpu/drm/mediatek/mediatek_drm_fb.c |  339 +
 drivers/gpu/drm/mediatek/mediatek_drm_fb.h |   43 +
 drivers/gpu/drm/mediatek/mediatek_drm_gem.c|  315 +
 drivers/gpu/drm/mediatek/mediatek_drm_gem.h|   94 ++
 include/uapi/drm/mediatek_drm.h|   59 +
 24 files changed, 4161 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
 create mode 100644 
Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt
 create mode 100644 drivers/gpu/drm/mediatek/Kconfig
 create mode 100644 drivers/gpu/drm/mediatek/Makefile
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_crtc.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_crtc.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_crtc_main.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_ddp_comp.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_drv.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_drv.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_dsi.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_dsi.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_fb.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_fb.h
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_gem.c
 create mode 100644 drivers/gpu/drm/mediatek/mediatek_drm_gem.h
 create mode 100644 include/uapi/drm/mediatek_drm.h

-- 
1.8.1.1.dirty


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 1/2] Dcumentation: bridge: Add documentation for ps8640 DT properties

2015-10-16 Thread CK Hu
From: Jitao Shi 

Add documentation for DT properties supported by ps8640
DSI-eDP converter.

Signed-off-by: Jitao Shi 
---
 .../devicetree/bindings/video/bridge/ps8640.txt|   48 
 1 file changed, 48 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/bridge/ps8640.txt

diff --git a/Documentation/devicetree/bindings/video/bridge/ps8640.txt 
b/Documentation/devicetree/bindings/video/bridge/ps8640.txt
new file mode 100644
index 000..450b5df
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/bridge/ps8640.txt
@@ -0,0 +1,48 @@
+ps8640-bridge bindings
+
+Required properties:
+   - compatible: "parade,ps8640"
+   - reg: first i2c address of the bridge
+   - power-gpios: OF device-tree gpio specification for power pin.
+   - reset-gpios: OF device-tree gpio specification for reset pin.
+   - mode-sel-gpios: OF device-tree gpio specification for mode-sel pin.
+   - ps8640-1v2-supply: OF device-tree regulator specification for 1v2.
+   - ps8640-3v3-supply: OF device-tree regulator specification for 3v3.
+
+Optional properties:
+   - video interfaces: Device node can contain video interface port
+   nodes for panel according to [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+   edp-bridge@18 {
+   compatible = "parade,ps8640";
+   reg = <0x18>;
+   power-gpios = < 116 GPIO_ACTIVE_HIGH>;
+   reset-gpios = < 115 GPIO_ACTIVE_HIGH>;
+   mode-sel-gpios = < 92 GPIO_ACTIVE_HIGH>;
+   ps8640-1v2-supply = <_fixed_1v2>;
+   ps8640-3v3-supply = <_vgp2_reg>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   ps8640_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   ps8640_out: endpoint {
+   remote-endpoint = <_in>;
+   };
+   };
+   };
+   };
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 2/2] drm/bridge: Add I2C based driver for ps8640 bridge

2015-10-16 Thread CK Hu
  ret = PTR_ERR(ps_bridge->gpio_pwr_n);
+   DRM_ERROR("cannot get gpio_pwr_n %d\n", ret);
+   return ret;
+   }
+
+   ret = gpiod_direction_output(ps_bridge->gpio_pwr_n, 1);
+   if (ret) {
+   DRM_ERROR("cannot configure gpio_pwr_n\n");
+   return ret;
+   }
+
+   ps_bridge->gpio_rst_n = devm_gpiod_get(>dev, "reset",
+  GPIOD_OUT_HIGH);
+   if (IS_ERR(ps_bridge->gpio_rst_n)) {
+   ret = PTR_ERR(ps_bridge->gpio_rst_n);
+   DRM_ERROR("cannot get gpio_rst_n %d\n", ret);
+   return ret;
+   }
+
+   ret = gpiod_direction_output(ps_bridge->gpio_rst_n, 1);
+   if (ret) {
+   DRM_ERROR("cannot configure gpio_rst_n\n");
+   return ret;
+   }
+
+   ret = of_property_read_u32(dev->of_node, "reg", _reg);
+   if (ret) {
+   DRM_ERROR("Can't read base_reg value\n");
+   return ret;
+   }
+   ps_bridge->base_reg = temp_reg;
+
+   ps_bridge->bridge.funcs = _bridge_funcs;
+   ps_bridge->bridge.of_node = dev->of_node;
+   ret = drm_bridge_add(_bridge->bridge);
+   if (ret) {
+   DRM_ERROR("Failed to add bridge\n");
+   return ret;
+   }
+
+   i2c_set_clientdata(client, ps_bridge);
+
+   return 0;
+}
+
+static int ps8640_remove(struct i2c_client *client)
+{
+   struct ps8640 *ps_bridge = i2c_get_clientdata(client);
+
+   drm_bridge_remove(_bridge->bridge);
+
+   return 0;
+}
+
+static const struct i2c_device_id ps8640_i2c_table[] = {
+   {"parade,ps8640", 0},
+   {},
+};
+MODULE_DEVICE_TABLE(i2c, ps8640_i2c_table);
+
+static const struct of_device_id ps8640_match[] = {
+   { .compatible = "parade,ps8640" },
+   {},
+};
+MODULE_DEVICE_TABLE(of, ps8640_match);
+
+static struct i2c_driver ps8640_driver = {
+   .id_table = ps8640_i2c_table,
+   .probe = ps8640_probe,
+   .remove = ps8640_remove,
+   .driver = {
+   .name = "parade,ps8640",
+   .owner = THIS_MODULE,
+   .of_match_table = ps8640_match,
+   },
+};
+module_i2c_driver(ps8640_driver);
+
+MODULE_AUTHOR("Jitao Shi <jitao@mediatek.com>");
+MODULE_AUTHOR("CK Hu <ck...@mediatek.com>");
+MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC v3 4/5] drm/mediatek: add support for Mediatek SoC MT2701

2016-06-12 Thread CK Hu
Hi, YT:

Some comments inline.

On Thu, 2016-06-09 at 00:03 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |6 
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|6 
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   42 
> +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |8 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |2 ++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   31 
>  6 files changed, 95 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index eb5c05e..1da0a71 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -286,11 +286,17 @@ static int mtk_disp_ovl_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_ddp_comp_driver_data mt2701_ovl_driver_data = {
> + .ovl = {0x0040, 1 << 12, 0}
> +};
> +
>  static const struct mtk_ddp_comp_driver_data mt8173_ovl_driver_data = {
>   .ovl = {0x0f40, 0, 1 << 12}
>  };
>  
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-ovl",
> +   .data = _ovl_driver_data},
>   { .compatible = "mediatek,mt8173-disp-ovl",
> .data = _ovl_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index fb0db50..506a353 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -225,11 +225,17 @@ static int mtk_disp_rdma_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_ddp_comp_driver_data mt2701_rdma_driver_data = {
> + .rdma_fifo_pseudo_size = SZ_4K,
> +};
> +
>  static const struct mtk_ddp_comp_driver_data mt8173_rdma_driver_data = {
>   .rdma_fifo_pseudo_size = SZ_8K,
>  };
>  
>  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-rdma",
> +   .data = _rdma_driver_data},
>   { .compatible = "mediatek,mt8173-disp-rdma",
> .data = _rdma_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index fa53806..7ab6986 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -32,6 +32,10 @@
>  #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN   0x0c8
>  #define DISP_REG_CONFIG_MMSYS_CG_CON00x100
>  
> +#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030
> +#define DISP_REG_CONFIG_OUT_SEL  0x04c
> +#define DISP_REG_CONFIG_DSI_SEL  0x050

Align the digital value.

> +
>  #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
>  #define DISP_REG_MUTEX(n)(0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)(0x28 + 0x20 * (n))
> @@ -54,6 +58,13 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1   BIT(24)
>  #define MT8173_MUTEX_MOD_DISP_OD BIT(25)
>  
> +#define MT2701_MUTEX_MOD_DISP_OVLBIT(3)
> +#define MT2701_MUTEX_MOD_DISP_WDMA   BIT(6)
> +#define MT2701_MUTEX_MOD_DISP_COLOR  BIT(7)
> +#define MT2701_MUTEX_MOD_DISP_BLSBIT(9)
> +#define MT2701_MUTEX_MOD_DISP_RDMA0  BIT(10)
> +#define MT2701_MUTEX_MOD_DISP_RDMA1  BIT(12)
> +
>  #define MUTEX_SOF_SINGLE_MODE0
>  #define MUTEX_SOF_DSI0   1
>  #define MUTEX_SOF_DSI1   2
> @@ -69,6 +80,10 @@
>  #define DPI0_SEL_IN_RDMA10x1
>  #define COLOR1_SEL_IN_OVL1   0x1
>  
> +#define OVL_MOUT_EN_RDMA 0x1
> +#define BLS_TO_DSI_RDMA1_TO_DPI1 0x8
> +#define DSI_SEL_IN_BLS   0x0
> +
>  struct mtk_disp_mutex {
>   int id;
>   bool claimed;
> @@ -82,6 +97,15 @@ struct mtk_ddp {
>   const unsigned int  *mutex_mod;
>  };
>  
> +static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> + [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
> + [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
> + [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
> + [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
> + [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
> + [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
> +};
> +
>  static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
>   [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
> @@ -109,6 +133,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id 
> cur,
>   if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
>   *addr = 

Re: [RFC v3 3/5] drm/mediatek: add shadow register support

2016-06-13 Thread CK Hu
Hi, YT:

One comment inline.

On Thu, 2016-06-09 at 00:03 +0800, YT Shen wrote:
> We need to acquire mutex before using the resources,
> and need to release it after finished.
> So we don't need to write registers in the blanking period.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |   75 
> +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   22 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |2 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |1 +
>  5 files changed, 72 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 24aa3ba..80d9641 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -315,6 +315,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
> *mtk_crtc)
>   pm_runtime_put(drm->dev);
>  }
>  
> +static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
> +{
> + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> + struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
> + unsigned int i;
> +
> + /*
> +  * TODO: instead of updating the registers here, we should prepare
> +  * working registers in atomic_commit and let the hardware command
> +  * queue update module registers on vblank.
> +  */
> + if (state->pending_config) {
> + mtk_ddp_comp_config(ovl, state->pending_width,
> + state->pending_height,
> + state->pending_vrefresh);
> +
> + state->pending_config = false;
> + }
> +
> + if (mtk_crtc->pending_planes) {
> + for (i = 0; i < OVL_LAYER_NR; i++) {
> + struct drm_plane *plane = _crtc->planes[i].base;
> + struct mtk_plane_state *plane_state;
> +
> + plane_state = to_mtk_plane_state(plane->state);
> +
> + if (plane_state->pending.config) {
> + mtk_ddp_comp_layer_config(ovl, i, plane_state);
> + plane_state->pending.config = false;
> + }
> + }
> + mtk_crtc->pending_planes = false;
> + }
> +}
> +
>  static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> @@ -391,6 +427,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
> struct drm_crtc_state *old_crtc_state)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_drm_private *priv = crtc->dev->dev_private;
>   unsigned int pending_planes = 0;
>   int i;
>  
> @@ -409,6 +446,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
>   }
>   if (pending_planes)
>   mtk_crtc->pending_planes = true;
> +
> + if (priv->data->shadow_register) {
> + mtk_disp_mutex_acquire(mtk_crtc->mutex);
> + mtk_crtc_ddp_config(crtc);
> + mtk_disp_mutex_release(mtk_crtc->mutex);
> + }
>  }
>  
>  static const struct drm_crtc_funcs mtk_crtc_funcs = {
> @@ -453,36 +496,10 @@ err_cleanup_crtc:
>  void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> - struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> - unsigned int i;
> + struct mtk_drm_private *priv = crtc->dev->dev_private;
>  
> - /*
> -  * TODO: instead of updating the registers here, we should prepare
> -  * working registers in atomic_commit and let the hardware command
> -  * queue update module registers on vblank.
> -  */
> - if (state->pending_config) {
> - mtk_ddp_comp_config(ovl, state->pending_width,
> - state->pending_height,
> - state->pending_vrefresh);
> -
> - state->pending_config = false;
> - }
> -
> - if (mtk_crtc->pending_planes) {
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = _crtc->planes[i].base;
> - struct mtk_plane_state *plane_state;
> -
> - plane_state = to_mtk_plane_state(plane->state);
> -
> - if (plane_state->pending.config) {
> - mtk_ddp_comp_layer_config(ovl, i, plane_state);
> - plane_state->pending.config = false;
> - }
> - }
> - mtk_crtc->pending_planes = false;
> - }
> + if (!priv->data->shadow_register)
> + mtk_crtc_ddp_config(crtc);
>  
>   mtk_drm_finish_page_flip(mtk_crtc);
>  }
> diff --git 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread CK Hu
Hi, HS:

Some comments inline.

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao <hs.l...@mediatek.com>
> Signed-off-by: CK Hu <ck...@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
> new file mode 100644
> index 000..e9d6e1c
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> @@ -0,0 +1,943 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> +#define CMDQ_INST_SIZE   8 /* instruction is 64-bit */
> +#define CMDQ_TIMEOUT_MS  1000
> +#define CMDQ_IRQ_MASK0x
> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> +#define CMDQ_CLK_NAME"gce"
> +
> +#define CMDQ_CURR_IRQ_STATUS 0x010
> +#define CMDQ_CURR_LOADED_THR 0x018
> +#define CMDQ_THR_SLOT_CYCLES 0x030
> +
> +#define CMDQ_THR_BASE0x100
> +#define CMDQ_THR_SHIFT   0x080
> +#define CMDQ_THR_WARM_RESET  0x00
> +#define CMDQ_THR_ENABLE_TASK 0x04
> +#define CMDQ_THR_SUSPEND_TASK0x08
> +#define CMDQ_THR_CURR_STATUS 0x0c
> +#define CMDQ_THR_IRQ_STATUS  0x10
> +#define CMDQ_THR_IRQ_ENABLE  0x14
> +#define CMDQ_THR_CURR_ADDR   0x20
> +#define CMDQ_THR_END_ADDR0x24
> +#define CMDQ_THR_CFG 0x40
> +
> +#define CMDQ_THR_ENABLED 0x1
> +#define CMDQ_THR_DISABLED0x0
> +#define CMDQ_THR_SUSPEND 0x1
> +#define CMDQ_THR_RESUME  0x0
> +#define CMDQ_THR_STATUS_SUSPENDEDBIT(1)
> +#define CMDQ_THR_DO_WARM_RESET   BIT(0)
> +#define CMDQ_THR_ACTIVE_SLOT_CYCLES  0x3200
> +#define CMDQ_THR_PRIORITY3
> +#define CMDQ_THR_IRQ_DONE0x1
> +#define CMDQ_THR_IRQ_ERROR   0x12
> +#de

Re: [PATCH v7 2/4] CMDQ: Mediatek CMDQ driver

2016-05-26 Thread CK Hu
Hi, HS:

Replay inline.

On Tue, 2016-05-24 at 20:27 +0800, Horng-Shyang Liao wrote:
> Hi CK,
> 
> Reply in line.
> 
> On Tue, 2016-05-24 at 11:05 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > Some comments below.
> > 
> ...
> > > +static void cmdq_thread_irq_handler(struct cmdq *cmdq, int tid)
> > > +{
> > > + struct cmdq_thread *thread = >thread[tid];
> > > + unsigned long flags = 0L;
> > > + int value;
> > > +
> > > + spin_lock_irqsave(>exec_lock, flags);
> > > +
> > > + /*
> > > +  * it is possible for another CPU core
> > > +  * to run "release task" right before we acquire the spin lock
> > > +  * and thus reset / disable this HW thread
> > > +  * so we check both the IRQ flag and the enable bit of this thread
> > > +  */
> > > + value = cmdq_thread_readl(thread, CMDQ_THR_IRQ_STATUS);
> > > + if (!(value & CMDQ_THR_IRQ_MASK)) {
> > > + spin_unlock_irqrestore(>exec_lock, flags);
> > > + return;
> > > + }
> > 
> > If this case happen and just return without clearing irq status, the irq
> > would keep triggering and system hang up. So just remove this checking
> > and go down to clear irq status.
> 
> This case is safe because irq status is cleared.
> But, next if condition has the problem which you mentioned.
> 
> I will change it as below.
> 
>   if (!(cmdq_thread_readl(thread, CMDQ_THR_ENABLE_TASK) &
> CMDQ_THR_ENABLED)) {
>   cmdq_thread_writel(thread, ~value, CMDQ_THR_IRQ_STATUS);
>   spin_unlock_irqrestore(>exec_lock, flags);
>   return;
>   }
> 
> If thread is disabled, tasks must be all finished.
> Therefore, just clear irq status and return.
> 

For irq status checking part, if irq status & irq mask is zero, remove
this checking and let it go down, it still do nothing because value &
CMDQ_THR_IRQ_ERROR is zero and value & CMDQ_THR_IRQ_DONE is zero. So you
can just remove this checking and get the same result.

In general HW design, once a HW is not enable, it does not trigger
interrupt any more. Be sure that it's necessary to clear irq status even
though thread is disable.


> > > +
> > > + if (!(cmdq_thread_readl(thread, CMDQ_THR_ENABLE_TASK) &
> > > +   CMDQ_THR_ENABLED)) {
> > > + spin_unlock_irqrestore(>exec_lock, flags);
> > > + return;
> > > + }
> > > +
> > > + cmdq_thread_writel(thread, ~value, CMDQ_THR_IRQ_STATUS);
> > > +
> > > + if (value & CMDQ_THR_IRQ_ERROR)
> > > + cmdq_handle_error_done(cmdq, thread, true);
> > > + else if (value & CMDQ_THR_IRQ_DONE)
> > > + cmdq_handle_error_done(cmdq, thread, false);
> > 
> > These irq status checking and clearing code here is the same as those in
> > cmdq_task_handle_error_result(). To move the checking and clearing code
> > into cmdq_handle_error_done() and here just to call
> > cmdq_handle_error_done(cmdq, thread) would reduce duplicated code.
> 
> Will do.
> 
> > > +
> > > + spin_unlock_irqrestore(>exec_lock, flags);
> > > +}
> ...
> ...
> > 
> > Regards,
> > CK
> 
> Thanks,
> HS
> 

Regards,
CK




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread CK Hu
Hi, HS:

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao <hs.l...@mediatek.com>
> Signed-off-by: CK Hu <ck...@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h

[...]

> +
> +/* events for CMDQ and display */
> +enum cmdq_event {
> + /* Display start of frame(SOF) events */
> + CMDQ_EVENT_DISP_OVL0_SOF = 11,
> + CMDQ_EVENT_DISP_OVL1_SOF = 12,
> + CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> + CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> + CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> + CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> + CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> + /* Display end of frame(EOF) events */
> + CMDQ_EVENT_DISP_OVL0_EOF = 39,
> + CMDQ_EVENT_DISP_OVL1_EOF = 40,
> + CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> + CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> + CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> + CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> + CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> + /* Mutex end of frame(EOF) events */
> + CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> + CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> + CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> + CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> + CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> + /* Display underrun events */
> + CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> + CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> + CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> + /* Keep this at the end of HW events */
> + CMDQ_MAX_HW_EVENT_COUNT = 260,
> +};

The value of these symbol is just the GCE-HW-defined value. I think it's
not appropriate to expose HW-defined value to client. For another SoC
GCE HW, these definition may change.

One way to solve this problem is to translate symbol to value
internally. But these events looks like interrupt and the value may vary
by each SoC, to prevent driver modified frequently, it's better to place
the value definition in device tree. It may looks like:

mmsys: clock-controller@1400 {
compatible = "mediatek,mt8173-mmsys";
mediatek,gce = <>;
gce-events = <53 54>;
gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
}

For cmdq driver, you just need modify interface from

int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)

to

int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)

Regards,
CK




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread CK Hu
On Thu, 2016-06-23 at 15:54 +0800, Horng-Shyang Liao wrote:
> Hi CK,
> 
> On Thu, 2016-06-23 at 14:03 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > [...]
> > 
> > > +
> > > +/* events for CMDQ and display */
> > > +enum cmdq_event {
> > > + /* Display start of frame(SOF) events */
> > > + CMDQ_EVENT_DISP_OVL0_SOF = 11,
> > > + CMDQ_EVENT_DISP_OVL1_SOF = 12,
> > > + CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> > > + CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> > > + CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> > > + CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> > > + CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> > > + /* Display end of frame(EOF) events */
> > > + CMDQ_EVENT_DISP_OVL0_EOF = 39,
> > > + CMDQ_EVENT_DISP_OVL1_EOF = 40,
> > > + CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> > > + CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> > > + CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> > > + CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> > > + CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> > > + /* Mutex end of frame(EOF) events */
> > > + CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> > > + CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> > > + CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> > > + CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> > > + CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> > > + /* Display underrun events */
> > > + CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> > > + CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> > > + CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> > > + /* Keep this at the end of HW events */
> > > + CMDQ_MAX_HW_EVENT_COUNT = 260,
> > > +};
> > 
> > The value of these symbol is just the GCE-HW-defined value. I think it's
> > not appropriate to expose HW-defined value to client. For another SoC
> > GCE HW, these definition may change.
> 
> Agree.
> 
> > One way to solve this problem is to translate symbol to value
> > internally. But these events looks like interrupt and the value may vary
> > by each SoC, to prevent driver modified frequently, it's better to place
> > the value definition in device tree. It may looks like:
> > 
> > mmsys: clock-controller@1400 {
> > compatible = "mediatek,mt8173-mmsys";
> > mediatek,gce = <>;
> > gce-events = <53 54>;
> 
> However, client still needs to know the HW-defined value by using
> this solution.
> 
> > gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
> > }
> > 
> > For cmdq driver, you just need modify interface from
> > 
> > int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
> > int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)
> > 
> > to
> > 
> > int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
> > int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)
> 
> I think an easy way for this issue is just removing HW-defined values
> from include/soc/mediatek/cmdq.h (but keeping enum), and then mapping
> abstract values into real values in driver.
> The benefit of this solution is that we can keep interface and leave SoC
> specific code into driver.
> What do you think?

Hi, HS:

OK, that's fine.

Regards,
CK

> 
> > Regards,
> > CK
> 
> Thanks,
> HS
> 
> 




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread CK Hu
Hi, HS:

One comment inline.

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao <hs.l...@mediatek.com>
> Signed-off-by: CK Hu <ck...@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile

[Snip...]

> +
> +static int cmdq_eng_get_thread(u64 flag)
> +{
> + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> + return CMDQ_THR_DISP_MAIN_IDX;
> + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> + return CMDQ_THR_DISP_SUB_IDX;
> + else
> + return CMDQ_THR_DISP_MISC_IDX;
> +}

I think cmdq should not have knowledge of client. These statement show
that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
the 'session' to replace engine flag. For example, main display create
one cmdq_session and external display create another cmdq_session. For
client driver, every tasks created by main display is bound to main
display session. For cmdq driver, it should dynamically bind a session
to a HW thread, and then dispatch tasks of this session to this HW
thread. After HW thread run out of tasks of this session, detach this
session with this thread.
For the problem of remove wfe cmd, I think a session can have a property
of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
For other client, it's false.

Here is the sample code to create cmdq_rec with session.

merge_wfe_cmd = true;
cmdq_session_create(merge_wfe_cmd, _display_session);
cmdq_rec_create(dev, primary_display_session, );


Therefore, the below definition can be removed.

> +
> +enum cmdq_eng {
> + CMDQ_ENG_DISP_AAL,
> + CMDQ_ENG_DISP_COLOR0,
> + CMDQ_ENG_DISP_COLOR1,
> + CMDQ_ENG_DISP_DPI0,
> + CMDQ_ENG_DISP_DSI0,
> + CMDQ_ENG_DISP_DSI1,
> + CMDQ_ENG_DISP_GAMMA,
> + CMDQ_ENG_DISP_OD,
> + CMDQ_ENG_DISP_OVL0,
> + CMDQ_ENG_DISP_OVL1,
> + CMDQ_ENG_DISP_PWM0,
> + CMDQ_ENG_DISP_PWM1,
> + CMDQ_ENG_DISP_RDMA0,
> + CMDQ_ENG_DISP_RDMA1,
> + CMDQ_ENG_DISP_RDMA2,
> + CMDQ_ENG_DISP_UFOE,
> + CMDQ_ENG_DISP_WDMA0,
> + CMDQ_ENG_DISP_WDMA1,
> + CMDQ_ENG_MAX,
> +};
> +


Regards,
CK



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread CK Hu
On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > One comment inline.
> > 
> > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > CMDQ is used to help read/write registers with critical time limitation,
> > > such as updating display configuration during the vblank. It controls
> > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > Currently, CMDQ only supports display related hardwares, but we expect
> > > it can be extended to other hardwares for future requirements.
> > > 
> > > Signed-off-by: HS Liao <hs.l...@mediatek.com>
> > > Signed-off-by: CK Hu <ck...@mediatek.com>
> > > ---
> > >  drivers/soc/mediatek/Kconfig|  10 +
> > >  drivers/soc/mediatek/Makefile   |   1 +
> > >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > > 
> > >  include/soc/mediatek/cmdq.h | 197 +
> > >  4 files changed, 1151 insertions(+)
> > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > >  create mode 100644 include/soc/mediatek/cmdq.h
> > > 
> > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > index 0a4ea80..c4ad75c 100644
> > > --- a/drivers/soc/mediatek/Kconfig
> > > +++ b/drivers/soc/mediatek/Kconfig
> > > @@ -1,6 +1,16 @@
> > >  #
> > >  # MediaTek SoC drivers
> > >  #
> > > +config MTK_CMDQ
> > > + bool "MediaTek CMDQ Support"
> > > + depends on ARCH_MEDIATEK || COMPILE_TEST
> > > + select MTK_INFRACFG
> > > + help
> > > +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > > +   driver. The CMDQ is used to help read/write registers with critical
> > > +   time limitation, such as updating display configuration during the
> > > +   vblank.
> > > +
> > >  config MTK_INFRACFG
> > >   bool "MediaTek INFRACFG Support"
> > >   depends on ARCH_MEDIATEK || COMPILE_TEST
> > > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > > index 12998b0..f7397ef 100644
> > > --- a/drivers/soc/mediatek/Makefile
> > > +++ b/drivers/soc/mediatek/Makefile
> > 
> > [Snip...]
> > 
> > > +
> > > +static int cmdq_eng_get_thread(u64 flag)
> > > +{
> > > + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > + return CMDQ_THR_DISP_MAIN_IDX;
> > > + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > + return CMDQ_THR_DISP_SUB_IDX;
> > > + else
> > > + return CMDQ_THR_DISP_MISC_IDX;
> > > +}
> > 
> > I think cmdq should not have knowledge of client. These statement show
> > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > the 'session' to replace engine flag. For example, main display create
> > one cmdq_session and external display create another cmdq_session. For
> > client driver, every tasks created by main display is bound to main
> > display session. For cmdq driver, it should dynamically bind a session
> > to a HW thread, and then dispatch tasks of this session to this HW
> > thread. After HW thread run out of tasks of this session, detach this
> > session with this thread.
> > For the problem of remove wfe cmd, I think a session can have a property
> > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > For other client, it's false.
> 
> Hi CK,
> 
> I think your suggestion is similar to CMDQ 'scenarios',
> which was removed from CMDQ v2.
> 
> Daniel suggests to use engine flags instead of scenarios.
> Quote from https://patchwork.kernel.org/patch/8068311/ .
> 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
>  cmdq driver should just provide these flag bits, and the display
>  subsystem can use them to build the "flag" parameter itself.
> 
>  After all, the exact configuration of mmsys components is somewhat
>  flexible.'
> 
> Therefore, it would be better to discuss with Daniel before we change
> it.
> 
> 
> Hi Daniel,
> 
> Do you think we should use scenarios or sessions instead of flags?
> 
> Thanks,
> HS
> 

Hi, HS:

'session' is not similar to 'scenarios'.

In 'scenarios' mechanism, client bind a task with scenarios and send to
cmdq. Cmdq transfer scenarios to engine flag, and use 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-26 Thread CK Hu
On Fri, 2016-06-24 at 19:39 +0800, Horng-Shyang Liao wrote:
> On Tue, 2016-06-21 at 15:46 +0800, Horng-Shyang Liao wrote:
> > On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> > > On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > > > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > > > [Snip...]
> > > > > 
> > > > > > +
> > > > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > > > +{
> > > > > > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > > > +   return CMDQ_THR_DISP_MAIN_IDX;
> > > > > > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > > > +   return CMDQ_THR_DISP_SUB_IDX;
> > > > > > +   else
> > > > > > +   return CMDQ_THR_DISP_MISC_IDX;
> > > > > > +}
> > > > > 
> > > > > I think cmdq should not have knowledge of client. These statement show
> > > > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > > > the 'session' to replace engine flag. For example, main display create
> > > > > one cmdq_session and external display create another cmdq_session. For
> > > > > client driver, every tasks created by main display is bound to main
> > > > > display session. For cmdq driver, it should dynamically bind a session
> > > > > to a HW thread, and then dispatch tasks of this session to this HW
> > > > > thread. After HW thread run out of tasks of this session, detach this
> > > > > session with this thread.
> > > > > For the problem of remove wfe cmd, I think a session can have a 
> > > > > property
> > > > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > > > For other client, it's false.
> > > > 
> > > > Hi CK,
> > > > 
> > > > I think your suggestion is similar to CMDQ 'scenarios',
> > > > which was removed from CMDQ v2.
> > > > 
> > > > Daniel suggests to use engine flags instead of scenarios.
> > > > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > > > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> > > >  cmdq driver should just provide these flag bits, and the display
> > > >  subsystem can use them to build the "flag" parameter itself.
> > > > 
> > > >  After all, the exact configuration of mmsys components is somewhat
> > > >  flexible.'
> > > > 
> > > > Therefore, it would be better to discuss with Daniel before we change
> > > > it.
> > > > 
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > Do you think we should use scenarios or sessions instead of flags?
> > > > 
> > > > Thanks,
> > > > HS
> > > > 
> > > 
> > > Hi, HS:
> > > 
> > > 'session' is not similar to 'scenarios'.
> > > 
> > > In 'scenarios' mechanism, client bind a task with scenarios and send to
> > > cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> > > dispatch task to HW thread.
> > > 
> > > 
> > > In 'engine flag' mechanism, proposed by Daniel, client bind a task
> > > directly with engine flag. Cmdq directly use engine flag to dispatch
> > > task to HW thread without any translation.
> > > 
> > > But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> > > engine flag, which make cmdq have knowledge of client.
> > > 
> > > In 'session' mechanism, there is no engine flag any more. Client bind
> > > time-sequential tasks to the same session and tasks in different session
> > > can execute parallelly. One thing cmdq need to know is to dispatch tasks
> > > with the same session to the same HW thread, so cmdq does not have any
> > > knowledge of client.
> > > 
> > > Daniel focus on reduce translating scenarios to engine flag. I think
> > > 'session' mechanism does not conflict with his opinion because we does
> > > not translate 'session' to engine flag. Therefore, I think 'session' is
> > > the best of these three mechanism.
> > > 
> > > Regards,
> > > CK
> > 
> > Hi CK,
> > 
> > 'Session' looks like a group of options for CMDQ.
> > CMDQ driver can just follow the 

Re: [PATCH v7 2/4] CMDQ: Mediatek CMDQ driver

2016-05-23 Thread CK Hu
Hi, HS:

Some comments below.

On Mon, 2016-05-23 at 20:23 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao <hs.l...@mediatek.com>
> Signed-off-by: CK Hu <ck...@mediatek.com>
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 904 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1112 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
> new file mode 100644
> index 000..f8c5d02
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> @@ -0,0 +1,904 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> +#define CMDQ_INST_SIZE   8 /* instruction is 64-bit */
> +
> +#define CMDQ_DEFAULT_TIMEOUT_MS  1000
> +
> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> +#define CMDQ_CLK_NAME"gce"
> +
> +#define CMDQ_CURR_IRQ_STATUS 0x010
> +#define CMDQ_THR_SLOT_CYCLES 0x030
> +
> +#define CMDQ_THR_BASE0x100
> +#define CMDQ_THR_SHIFT   0x080
> +#define CMDQ_THR_WARM_RESET  0x00
> +#define CMDQ_THR_ENABLE_TASK 0x04
> +#define CMDQ_THR_SUSPEND_TASK0x08
> +#define CMDQ_THR_CURR_STATUS 0x0c
> +#define CMDQ_THR_IRQ_STATUS  0x10
> +#define CMDQ_THR_IRQ_ENABLE  0x14
> +#define CMDQ_THR_CURR_ADDR   0x20
> +#define CMDQ_THR_END_ADDR0x24
> +#define CMDQ_THR_CFG 0x40
> +
> +#define CMDQ_IRQ_MASK0x
> +
> +#define CMDQ_THR_ENABLED 0x1
> +#define CMDQ_THR_DISABLED0x0
> +#define CMDQ_THR_SUSPEND 0x1
> +#define CMDQ_THR_RESUME  0x0
> +#define CMDQ_THR_STATUS_SUSPENDEDBIT(1)
> +#define CMDQ_THR_DO_WARM_RESET   BIT(0)
> +#define CMDQ_THR_ACTIVE_SLOT_CYCLES  0x3200
> +#define CMDQ_THR_PRIORITY3
> +#define CMDQ_THR_IRQ_DONE0x1
> +#define CMDQ_THR_IRQ_ERROR   0x12
> +#define CMDQ_THR_IRQ_EN  0x1

Re: [RFC v2 2/5] drm/mediatke: add support for Mediatek SoC MT2701

2016-05-23 Thread CK Hu
Hi, YT:

Some comments below.

On Fri, 2016-05-20 at 23:05 +0800, yt.s...@mediatek.com wrote:
> From: YT Shen 
> 
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 
>  
> +static void mtk_ddp_mux_sel(void __iomem *config_regs,
> + enum mtk_ddp_comp_id cur, enum mtk_ddp_comp_id next)
> +{
> + if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
> + writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
> +config_regs + DISP_REG_CONFIG_OUT_SEL);
> + }
> +}
> +

The function name 'mux' looks strange. The register written here
controls the single output selection. I prefer to rename it as
mtk_ddp_sout_sel().

>  
> -static const enum mtk_ddp_comp_id mtk_ddp_main[] = {
> +static const enum mtk_ddp_comp_id mtk_ddp_main_2701[] = {
> + DDP_COMPONENT_OVL0,
> + DDP_COMPONENT_RDMA0,
> + DDP_COMPONENT_COLOR0,
> + DDP_COMPONENT_BLS,
> + DDP_COMPONENT_DSI0,
> +};
> +
> +static const enum mtk_ddp_comp_id mtk_ddp_ext_2701[] = {
> + DDP_COMPONENT_OVL0,
> + DDP_COMPONENT_DSI0,
> +};
> +

These two pipelines has the same component such as OVL0 and DSI0. I
think user program could not enable both crtc at the same time. Maybe
MT2701 has only one crtc, so you should modify initial flow to create
only one crtc for main display. Or it's typo for external display pipe,
please correct it.


Regards,
CK



Re: [RFC v2 3/5] drm/mediatek: add *driver_data for different hardware settings

2016-05-23 Thread CK Hu
Hi, YT:

One comment below.

On Fri, 2016-05-20 at 23:05 +0800, yt.s...@mediatek.com wrote:
> From: YT Shen 
> 
> There are some hardware settings changed, between MT8173 & MT2701:
> DISP_OVL address offset changed, color format definition changed.
> DISP_RDMA fifo size changed.
> DISP_COLOR offset changed.
> 
> Signed-off-by: YT Shen 
> ---
> +
> +static inline struct mtk_ddp_comp_driver_data *mtk_ovl_get_driver_data(
> + struct platform_device *pdev)
> +{
> + const struct of_device_id *of_id =
> + of_match_device(mtk_disp_ovl_driver_dt_match, >dev);
> +
> + return (struct mtk_ddp_comp_driver_data *)of_id->data;
> +}
> +
> +static inline struct mtk_ddp_comp_driver_data *mtk_rdma_get_driver_data(
> + struct platform_device *pdev)
> +{
> + const struct of_device_id *of_id =
> + of_match_device(mtk_disp_rdma_driver_dt_match, >dev);
> +
> + return (struct mtk_ddp_comp_driver_data *)of_id->data;
> +}
> +
> +static inline struct mtk_ddp_comp_driver_data *mtk_color_get_driver_data(
> + struct device_node *node)
> +{
> + const struct of_device_id *of_id =
> + of_match_node(mtk_disp_color_driver_dt_match, node);
> +
> + return (struct mtk_ddp_comp_driver_data *)of_id->data;
> +}
> + 

These three functions looks the same with different parameter:
mtk_disp_ovl_driver_dt_match, mtk_disp_rdma_driver_dt_match, and
mtk_disp_color_driver_dt_match. So merge them to prevent duplicated
code.

Regards,
CK




Re: [PATCH v7 4/4] CMDQ: suspend/resume protection

2016-05-24 Thread CK Hu
On Mon, 2016-05-23 at 20:23 +0800, HS Liao wrote:
> Add suspend/resume protection mechanism to prevent active task(s) in
> suspend.
> 
> Signed-off-by: HS Liao 
> ---
>  drivers/soc/mediatek/mtk-cmdq.c | 174 
> ++--
>  1 file changed, 166 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
> index f8c5d02..1a51cfb 100644
> --- a/drivers/soc/mediatek/mtk-cmdq.c
> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> @@ -39,6 +39,7 @@
>  #define CMDQ_CLK_NAME"gce"
>  
>  #define CMDQ_CURR_IRQ_STATUS 0x010
> +#define CMDQ_CURR_LOADED_THR 0x018
>  #define CMDQ_THR_SLOT_CYCLES 0x030
>  
>  #define CMDQ_THR_BASE0x100
> @@ -125,6 +126,7 @@ enum cmdq_code {
>  
>  enum cmdq_task_state {
>   TASK_STATE_BUSY,/* task running on a thread */
> + TASK_STATE_KILLED,  /* task process being killed */
>   TASK_STATE_ERROR,   /* task execution error */
>   TASK_STATE_DONE,/* task finished */
>  };
> @@ -161,8 +163,12 @@ struct cmdq {
>   u32 irq;
>   struct workqueue_struct *task_release_wq;
>   struct cmdq_thread  thread[CMDQ_THR_MAX_COUNT];
> - spinlock_t  exec_lock;  /* for exec task */
> + atomic_tthread_usage;
> + struct mutextask_mutex; /* for task */
> + spinlock_t  exec_lock;  /* for exec */
>   struct clk  *clock;
> + boolsuspending;
> + boolsuspended;
>  };
>  
>  struct cmdq_subsys {
> @@ -196,15 +202,27 @@ static int cmdq_eng_get_thread(u64 flag)
>   return CMDQ_THR_DISP_MISC_IDX;
>  }
>  
> -static void cmdq_task_release(struct cmdq_task *task)
> +static void cmdq_task_release_unlocked(struct cmdq_task *task)
>  {
>   struct cmdq *cmdq = task->cmdq;
>  
> + /* This func should be inside cmdq->task_mutex mutex */
> + lockdep_assert_held(>task_mutex);
> +
>   dma_free_coherent(cmdq->dev, task->command_size, task->va_base,
> task->mva_base);
>   kfree(task);
>  }
>  
> +static void cmdq_task_release(struct cmdq_task *task)
> +{
> + struct cmdq *cmdq = task->cmdq;
> +
> + mutex_lock(>task_mutex);
> + cmdq_task_release_unlocked(task);
> + mutex_unlock(>task_mutex);
> +}
> +
>  static struct cmdq_task *cmdq_task_acquire(struct cmdq_rec *rec,
>  struct cmdq_task_cb cb)
>  {
> @@ -576,6 +594,12 @@ static int cmdq_task_wait_and_release(struct cmdq_task 
> *task)
>   dev_dbg(dev, "timeout!\n");
>  
>   spin_lock_irqsave(>exec_lock, flags);
> +
> + if (cmdq->suspending && task->task_state == TASK_STATE_KILLED) {
> + spin_unlock_irqrestore(>exec_lock, flags);
> + return 0;
> + }
> +
>   if (task->task_state != TASK_STATE_DONE)
>   err = cmdq_task_handle_error_result(task);
>   if (list_empty(>task_busy_list))
> @@ -584,7 +608,9 @@ static int cmdq_task_wait_and_release(struct cmdq_task 
> *task)
>  
>   /* release regardless of success or not */
>   clk_disable_unprepare(cmdq->clock);
> - cmdq_task_release(task);
> + atomic_dec(>thread_usage);
> + if (!(task->cmdq->suspending && task->task_state == TASK_STATE_KILLED))
> + cmdq_task_release(task);
>  
>   return err;
>  }
> @@ -597,12 +623,28 @@ static void cmdq_task_wait_release_work(struct 
> work_struct *work_item)
>   cmdq_task_wait_and_release(task);
>  }
>  
> -static void cmdq_task_wait_release_schedule(struct cmdq_task *task)
> +static void cmdq_task_wait_release_schedule(struct cmdq *cmdq,
> + struct cmdq_task *task)
>  {
> - struct cmdq *cmdq = task->cmdq;
> + unsigned long flags;
> +
> + spin_lock_irqsave(>exec_lock, flags);
> +
> + if (cmdq->suspending || cmdq->suspended) {
> + /*
> +  * This means system is suspened between
> +  * cmdq_task_submit_async() and
> +  * cmdq_task_wait_release_schedule(), so return immediately.
> +  * This task should be forced to remove by suspend flow.
> +  */
> + spin_unlock_irqrestore(>exec_lock, flags);
> + return;
> + }
>  
>   INIT_WORK(>release_work, cmdq_task_wait_release_work);
>   queue_work(cmdq->task_release_wq, >release_work);
> +
> + spin_unlock_irqrestore(>exec_lock, flags);
>  }
>  
>  static int cmdq_rec_realloc_cmd_buffer(struct cmdq_rec *rec, size_t size)
> @@ -766,18 +808,31 @@ static int _cmdq_rec_flush(struct cmdq_rec *rec, struct 
> cmdq_task **task_out,
>   struct cmdq_thread *thread;
>   int err;
>  
> + mutex_lock(>task_mutex);
> + if (rec->cmdq->suspending || rec->cmdq->suspended) {
> + 

Re: [RFC 2/3] drm/mediatek: add support for Mediatek SoC MT2701

2016-05-12 Thread CK Hu
Hi, YT:

On Thu, 2016-05-12 at 19:49 +0800, yt.s...@mediatek.com wrote:
> From: YT Shen 
> 
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701, and we have shadow
> register support here.
> 
> Signed-off-by: YT Shen 
> ---

> @@ -385,12 +422,16 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc 
> *crtc,
>   mtk_crtc->event = state->base.event;
>   state->base.event = NULL;
>   }
> +
> + if (priv->data->shadow_register)
> + mtk_disp_mutex_acquire(mtk_crtc->mutex);
>  }
>  
> @@ -409,6 +450,11 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
>   }
>   if (pending_planes)
>   mtk_crtc->pending_planes = true;
> +
> + if (priv->data->shadow_register) {
> + mtk_crtc_ddp_config(crtc);
> + mtk_disp_mutex_release(mtk_crtc->mutex);
> + }
>  }
>  

I think it's better to call mtk_disp_mutex_acquire() and
mtk_disp_mutex_release() as near as possible to prevent mutex locked for
a long time. All HW register access of this atomic setting is in
mtk_crtc_ddp_config(), so it's better to move mtk_disp_mutex_acquire()
just before mtk_crtc_ddp_config().

Regards,
CK



Re: [PATCH v3] arm64: dts: mt8173: add mmsel clocks for 4K support

2016-07-27 Thread CK Hu
Hi, Bibby:

On Wed, 2016-07-27 at 16:25 +0800, Bibby Hsieh wrote:
> If MT8173 can support HDMI 4K resoultion, the
> VENCPLL should be configured to 800MHZ.
> We didn't set VENCPLL directly, we set the
> mm_sel to 400MHz statically in the board device tree.

You may rewrite the description as below:

'To support HDMI 4K resolution, mmsys need clock mm_sel to be 400MHz.'

You need not to mention VENCPLL because it's controlled by clock driver.

> 
> Signed-off-by: Bibby Hsieh 
> ---
> Changes since v2:
>  - Align the clocks of dpi0 node.
> 
> Changes since v1:
>  - Do not set the VENCPLL by clk_set_rate
>at display driver.
>  - Configure the mm_sel to 400MHz statically
>in the board device tree.
> ---
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi |2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
> b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> index 78529e4..9c22204 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> @@ -690,7 +690,9 @@
>   compatible = "mediatek,mt8173-mmsys", "syscon";
>   reg = <0 0x1400 0 0x1000>;
>   power-domains = < MT8173_POWER_DOMAIN_MM>;
> + clocks = < CLK_TOP_MM_SEL>;
>   #clock-cells = <1>;
> + clock-frequency  = <4>;
>   };
>  
>   ovl0: ovl@1400c000 {

Regards,
CK



Re: [PATCH 3/4] drm/mediatek: fix the wrong pixel clock when resolution is 4K

2016-07-25 Thread CK Hu
Hi, Bibby:

On Mon, 2016-07-25 at 14:24 +0800, Bibby Hsieh wrote:
> Hi, CK,
> 
> Thanks for your comments.
> 
> On Wed, 2016-07-20 at 15:57 +0800, CK Hu wrote:
> > Hi, Bibby:
> > 
> > Some comments inline.
> > 
> > On Wed, 2016-07-20 at 12:03 +0800, Bibby Hsieh wrote:
> > > From: Junzhi Zhao <junzhi.z...@mediatek.com>
> > > 
> > > Pixel clock should be 297MHz when resolution is 4K.
> > > 
> > > Signed-off-by: Junzhi Zhao <junzhi.z...@mediatek.com>
> > > Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_dpi.c |  184 
> > > +---
> > >  1 file changed, 131 insertions(+), 53 deletions(-)
> > > 

[snip...]

> > >  
> > > +static int mt8173_parse_clk_from_dt(struct mtk_dpi *dpi, struct 
> > > device_node *np)
> > > +{
> > > + int i;
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(mtk_dpi_clk_names); i++) {
> > > + dpi->clk[i] = of_clk_get_by_name(np,
> > > +   mtk_dpi_clk_names[i]);
> > > + if (IS_ERR(dpi->clk[i]))
> > > + return PTR_ERR(dpi->clk[i]);
> > > + }
> > > + return 0;
> > > +}
> > 
> > I think parsing device tree is a pure SW behavior. Would this vary for
> > different MTK soc?
> > 
> Yes

I can not imaging that, so could you give me an example source code of
other MTK soc for parse_clk_from_dt()?

> > > +
> > > +
> > > +static const struct mtk_dpi_conf mt8173_conf = {
> > > + .parse_clk_from_dt = mt8173_parse_clk_from_dt,
> > > + .clk_config = mt8173_clk_config,
> > > +};
> > > +
> > > +static const struct of_device_id mtk_dpi_of_ids[] = {
> > > + { .compatible = "mediatek,mt8173-dpi",
> > > + .data = _conf,
> > > + },
> > > + {}
> > > +};
> > > +
> > >  static int mtk_dpi_probe(struct platform_device *pdev)
> > >  {
> > >   struct device *dev = >dev;
> > >   struct mtk_dpi *dpi;
> > >   struct resource *mem;
> > > + struct device_node *np = dev->of_node;
> > >   struct device_node *ep, *bridge_node = NULL;
> > >   int comp_id;
> > > + const struct of_device_id *match;
> > > + struct mtk_dpi_conf *conf;
> > >   int ret;
> > >  
> > > + match = of_match_node(mtk_dpi_of_ids, dev->of_node);
> > > + if (!match)
> > > + return -ENODEV;
> > > +
> > >   dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
> > >   if (!dpi)
> > >   return -ENOMEM;
> > >  
> > >   dpi->dev = dev;
> > > + dpi->data = (void *)match->data;
> > > + conf = (struct mtk_dpi_conf *)match->data;
> > >  
> > >   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > >   dpi->regs = devm_ioremap_resource(dev, mem);
> > > @@ -679,24 +777,9 @@ static int mtk_dpi_probe(struct platform_device 
> > > *pdev)
> > >   return ret;
> > >   }
> > >  
> > > - dpi->engine_clk = devm_clk_get(dev, "engine");
> > > - if (IS_ERR(dpi->engine_clk)) {
> > > - ret = PTR_ERR(dpi->engine_clk);
> > > - dev_err(dev, "Failed to get engine clock: %d\n", ret);
> > > - return ret;
> > > - }
> > > -
> > > - dpi->pixel_clk = devm_clk_get(dev, "pixel");
> > > - if (IS_ERR(dpi->pixel_clk)) {
> > > - ret = PTR_ERR(dpi->pixel_clk);
> > > - dev_err(dev, "Failed to get pixel clock: %d\n", ret);
> > > - return ret;
> > > - }
> > > -
> > > - dpi->tvd_clk = devm_clk_get(dev, "pll");
> > > - if (IS_ERR(dpi->tvd_clk)) {
> > > - ret = PTR_ERR(dpi->tvd_clk);
> > > - dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
> > > + ret = conf->parse_clk_from_dt(dpi, np);
> > > + if (ret) {
> > > + dev_err(dev, "parse tvd div clk failed!");
> > >   return ret;
> > >   }
> > >  
> > > @@ -754,11 +837,6 @@ static int mtk_dpi_remove(struct platform_device 
> > > *pdev)
> > >   return 0;
> > >  }
> > >  
> > > -static const struct of_device_id mtk_dpi_of_ids[] = {
> > > - { .compatible = "mediatek,mt8173-dpi", },
> > > - {}
> > > -};
> > > -
> > >  struct platform_driver mtk_dpi_driver = {
> > >   .probe = mtk_dpi_probe,
> > >   .remove = mtk_dpi_remove,
> > 
> > Regards,
> > CK
> > 
> 


Regards,
CK
> 




Re: [PATCH v4 4/8] drm/mediatek: add support for Mediatek SoC MT2701

2016-07-28 Thread CK Hu
Hi, YT:


On Thu, 2016-07-28 at 15:17 +0800, YT Shen wrote:
> Hi Philipp, CK,
> 
> On Thu, 2016-07-28 at 10:07 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Wed, 2016-07-27 at 12:03 +0200, Philipp Zabel wrote:
> > > Am Dienstag, den 26.07.2016, 18:42 +0800 schrieb YT Shen:
> > > > Hi CK,
> > > > 
> > > > On Wed, 2016-07-20 at 14:53 +0800, CK Hu wrote:
> > > > > Hi, YT:
> > > > > 
> > > > > Some comments inline.
> > > > > 
> > > > > On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> > > > > > This patch add support for the Mediatek MT2701 DISP subsystem.
> > > > > > There is only one OVL engine in MT2701.
> > > > > > 
> > > > > > Signed-off-by: YT Shen <yt.s...@mediatek.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |6 
> > > > > >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|6 
> > > > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   41 
> > > > > > +++
> > > > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |7 +
> > > > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |1 +
> > > > > >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   31 
> > > > > > 
> > > > > >  6 files changed, 92 insertions(+)
> > > > > > 
> > > > > 
> > > > > [snip...]
> > > > > 
> > > > > >  
> > > > > >  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> > > > > > +   { .compatible = "mediatek,mt2701-disp-ovl",   .data = (void 
> > > > > > *)MTK_DISP_OVL },
> > > > > > { .compatible = "mediatek,mt8173-disp-ovl",   .data = (void 
> > > > > > *)MTK_DISP_OVL },
> > > > > > +   { .compatible = "mediatek,mt2701-disp-rdma",  .data = (void 
> > > > > > *)MTK_DISP_RDMA },
> > > > > > { .compatible = "mediatek,mt8173-disp-rdma",  .data = (void 
> > > > > > *)MTK_DISP_RDMA },
> > > > > > +   { .compatible = "mediatek,mt2701-disp-wdma",  .data = (void 
> > > > > > *)MTK_DISP_WDMA },
> > > > > 
> > > > > Is WDMA different from MT8173 to MT2701. If they are the same, you 
> > > > > need
> > > > > not to add compatible of 'mediatek,mt2701-disp-wdma' because use
> > > > > 'mediatek,mt8173-disp-wdma' is enough.
> > > > Yes, the hardware has differences, so we need add new compatible
> > > > 'mt2701-disp-wdma'
> > > 
> > > It would be nice if you could add a short paragraph to the patch
> > > description about what the hardware differences are (probably just
> > > changed register layout in most cases).
> Thanks for the suggestions, we will add more descriptions in the future.
> 
> > 
> > If you don't want to add description, you may separate the modification
> > of OVL, RDMA, WDMA, PWM to different patch. And you send patch of OVL
> > and RDMA first because you have related code modification for these two.
> > You temporarily treat WDMA and PWM as MT8173 and it works. And one day
> > you need to modify code of WDMA and PWM for MT2701, then you send the
> > patch of WDMA and PWM and you need not to add any description because we
> > can find out the difference from source code.
> 
> The display module connections is shown in mt2701_mtk_ddp_main[] and
> mt2701_mtk_ddp_ext[].
> OVL -> RDMA -> COLOR -> BLS(pwm) -> DSI
> RDMA -> DPI
> 
> This patch series mainly focus on DSI support for MT2701 SoC and the
> basic functions.  The BLS(pwm) and DPI parts are not included here.
> 
> We will remove 'mt2701-disp-wdma'. We didn't implement its driver and it
> is unused now.
> 
> For the pwm part, we need the device node to establish the display
> module connections.  The pwm compatible string is described in
> "dt-bindings: pwm: Add MediaTek display PWM bindings" [1] and the
> control is implemented in "pwm: Add MediaTek MT2701 display PWM driver
> support" [2].
> 
> For the dpi part, we need the device node to establish the display
> module connections.  The dpi patch will be in another patch series,
> split out from "drm/mediatek: fix the wrong pixel clock when resolution
> is 4K" [3].

For dpi part, I think you need not to include it in this patch. You can
send it with the MT2701 DPI patch. For module connection, you can use
"mediatek,mt8173-dpi" and it works. If you want to add it in this patch,
please describe the difference of mt8173-dpi and mt2701-dpi in this
patch.

> 
> 
> [1] https://patchwork.kernel.org/patch/9222997/
> [2] https://patchwork.kernel.org/patch/9223001/
> [3] https://patchwork.kernel.org/patch/9249471/ 
> 
> Regards,
> yt.shen
> 
> > 
> > > 
> > > regards
> > > Philipp
> > > 
> > 
> > Regards,
> > CK
> > 
> 
> 

Regards,
CK



Re: [PATCH 2/7] drm/mediatek: plane: Remove plane zpos/index

2016-07-29 Thread CK Hu
Hi, Bibby:

On Fri, 2016-07-29 at 17:04 +0800, Bibby Hsieh wrote:
> From: Daniel Kurtz 
> 
> It is not actually useful to a mtk plane to know its zpos/index, so just
> remove this field.
> 
> This let's us completely remove struct mtk_drm_plane in a follow up patch.

'let's us'? My English is not as good as native English speaker.
Otherwise, this patch looks good to me.

> 
> Signed-off-by: Daniel Kurtz 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
>  drivers/gpu/drm/mediatek/mtk_drm_plane.c |4 +---
>  drivers/gpu/drm/mediatek/mtk_drm_plane.h |4 +---
>  3 files changed, 3 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 24aa3ba..18211ab 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -559,7 +559,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>   (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
>   DRM_PLANE_TYPE_OVERLAY;
>   ret = mtk_plane_init(drm_dev, _crtc->planes[zpos],
> -  BIT(pipe), type, zpos);
> +  BIT(pipe), type);
>   if (ret)
>   goto unprepare;
>   }
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index 093db07..d28db57 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -189,8 +189,7 @@ static const struct drm_plane_helper_funcs 
> mtk_plane_helper_funcs = {
>  };
>  
>  int mtk_plane_init(struct drm_device *dev, struct mtk_drm_plane *mtk_plane,
> -unsigned long possible_crtcs, enum drm_plane_type type,
> -unsigned int zpos)
> +unsigned long possible_crtcs, enum drm_plane_type type)
>  {
>   int err;
>  
> @@ -203,7 +202,6 @@ int mtk_plane_init(struct drm_device *dev, struct 
> mtk_drm_plane *mtk_plane,
>   }
>  
>   drm_plane_helper_add(_plane->base, _plane_helper_funcs);
> - mtk_plane->idx = zpos;
>  
>   return 0;
>  }
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h 
> b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> index 72a7b3e..74dbeda 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> @@ -20,7 +20,6 @@
>  
>  struct mtk_drm_plane {
>   struct drm_planebase;
> - unsigned intidx;
>  };
>  
>  struct mtk_plane_pending_state {
> @@ -53,7 +52,6 @@ to_mtk_plane_state(struct drm_plane_state *state)
>  }
>  
>  int mtk_plane_init(struct drm_device *dev, struct mtk_drm_plane *mtk_plane,
> -unsigned long possible_crtcs, enum drm_plane_type type,
> -unsigned int zpos);
> +unsigned long possible_crtcs, enum drm_plane_type type);
>  
>  #endif

Regards,
CK




Re: [PATCH v4 4/8] drm/mediatek: add support for Mediatek SoC MT2701

2016-07-27 Thread CK Hu
Hi, YT:

On Wed, 2016-07-27 at 12:03 +0200, Philipp Zabel wrote:
> Am Dienstag, den 26.07.2016, 18:42 +0800 schrieb YT Shen:
> > Hi CK,
> > 
> > On Wed, 2016-07-20 at 14:53 +0800, CK Hu wrote:
> > > Hi, YT:
> > > 
> > > Some comments inline.
> > > 
> > > On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> > > > This patch add support for the Mediatek MT2701 DISP subsystem.
> > > > There is only one OVL engine in MT2701.
> > > > 
> > > > Signed-off-by: YT Shen <yt.s...@mediatek.com>
> > > > ---
> > > >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |6 
> > > >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|6 
> > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   41 
> > > > +++
> > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |7 +
> > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |1 +
> > > >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   31 
> > > >  6 files changed, 92 insertions(+)
> > > > 
> > > 
> > > [snip...]
> > > 
> > > >  
> > > >  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> > > > +   { .compatible = "mediatek,mt2701-disp-ovl",   .data = (void 
> > > > *)MTK_DISP_OVL },
> > > > { .compatible = "mediatek,mt8173-disp-ovl",   .data = (void 
> > > > *)MTK_DISP_OVL },
> > > > +   { .compatible = "mediatek,mt2701-disp-rdma",  .data = (void 
> > > > *)MTK_DISP_RDMA },
> > > > { .compatible = "mediatek,mt8173-disp-rdma",  .data = (void 
> > > > *)MTK_DISP_RDMA },
> > > > +   { .compatible = "mediatek,mt2701-disp-wdma",  .data = (void 
> > > > *)MTK_DISP_WDMA },
> > > 
> > > Is WDMA different from MT8173 to MT2701. If they are the same, you need
> > > not to add compatible of 'mediatek,mt2701-disp-wdma' because use
> > > 'mediatek,mt8173-disp-wdma' is enough.
> > Yes, the hardware has differences, so we need add new compatible
> > 'mt2701-disp-wdma'
> 
> It would be nice if you could add a short paragraph to the patch
> description about what the hardware differences are (probably just
> changed register layout in most cases).

If you don't want to add description, you may separate the modification
of OVL, RDMA, WDMA, PWM to different patch. And you send patch of OVL
and RDMA first because you have related code modification for these two.
You temporarily treat WDMA and PWM as MT8173 and it works. And one day
you need to modify code of WDMA and PWM for MT2701, then you send the
patch of WDMA and PWM and you need not to add any description because we
can find out the difference from source code.

> 
> regards
> Philipp
> 

Regards,
CK



Re: [PATCH v6 07/10] drm/mediatek: add dsi transfer function

2016-08-11 Thread CK Hu
Hi, YT:

On Wed, 2016-08-10 at 15:24 +0800, YT Shen wrote:
> Hi CK,
> 
> On Fri, 2016-08-05 at 18:08 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Thu, 2016-08-04 at 19:07 +0800, YT Shen wrote:
> > > From: shaoming chen <shaoming.c...@mediatek.com>
> > > 
> > > add dsi read/write commands for transfer function
> > > 
> > > Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_dsi.c |  261 
> > > 
> > >  1 file changed, 261 insertions(+)
> > > 

[snip...]

> > > +
> > > +static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg 
> > > *msg)
> > > +{
> > > + const char *tx_buf = msg->tx_buf;
> > > + u32 reg_val, i;
> > > + u16 wc16;
> > > + u8 config, data0, data1, type;
> > > +
> > > + if (MTK_DSI_HOST_IS_READ(type)) {
> > 
> > 'type' is used before assigned.
> Will fix.
> 
> > 
> > > + config = 4;
> > > + data0 = tx_buf[0];
> > > +
> > > + if (msg->rx_len < 3)
> > > + type = MIPI_DSI_DCS_READ;
> > > + else
> > > + type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
> > > +
> > > + data1 = 0;
> > > + reg_val = (data1 << 24) | (data0 << 16) | (type << 8) | config;
> > > +
> > > + writel(reg_val, dsi->regs + DSI_CMDQ0);
> > > + mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, 1);
> > 
> > I think this part looks like 'else' part. The difference is type and
> > config. I think type should be msg->type and you can independently set
> > BIT(2) of config.
> msg->type only tells about read or write, for the details we need to
> check other parameters.  This part is for read, the else part is for
> write short packet.  Not only BIT(2) of config is different, but also
> type and data1 is changed.  Such a change would lead to difficult to
> understand.
> 
> > 
> > > + } else if (msg->tx_len > 2) {   /* send long packet */
> > > + config = 2;
> > > + type = msg->type;
> > > + wc16 = msg->tx_len;
> > > +
> > > + reg_val = (wc16 << 16) | (type << 8) | config;
> > > +
> > > + writel(reg_val, dsi->regs + DSI_CMDQ0);
> > > +
> > > + for (i = 0; i < msg->tx_len; i++)
> > > + writeb(tx_buf[i], dsi->regs + DSI_CMDQ0 + 4 + i);
> > > +
> > > + mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE,
> > > +  1 + (msg->tx_len + 3) / 4);
> > > + } else {/* send short packet */
> > > + config = 0;
> > > + data0 = tx_buf[0];
> > > +
> > > + if (msg->tx_len == 2) {
> > > + type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
> > 
> > Why do you not set type as msg->type? This behavior looks like you
> > modify transfer type, but is this acceptable?
> msg->type only tells about read or write, for the details we need to
> check other parameters.

I think you could rewrite mtk_dsi_cmdq() as follow:

static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg
*msg)
{
u32 i;
u32 src_off = (msg->tx_len > 2) ? 4 : 2;
u32 cmdq_size = (msg->tx_len > 2) ? 1 + (msg->tx_len + 3) / 4 : 1;
u32 config = (msg->tx_len > 2) ? BIT(1) : 0;
u32 type = msg->type;

if (MTK_DSI_HOST_IS_READ(type))
config |= BIT(2);

writel((type << 8) || config, dsi->regs + DSI_CMDQ0);
for (i = 0; i < msg->tx_len; i++)
writeb(msg->tx_buf[i], dsi->regs + DSI_CMDQ0 + src_off + i);
mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size);
}

If DSI HW does not support some type and it can be transferred to other
type, you could add a transfer function like this

static u8 mtk_dsi_map_to_supported_type(u8 type)
{
switch(type) {
case MIPI_DSI_DCS_SHORT_WRITE:
return MIPI_DSI_DCS_SHORT_WRITE_PARAM;
}

return type;
}

and then

u32 type = mtk_dsi_map_to_supported_type(msg->type);

> 
> > 
> > > + data1 = tx_buf[1];
> > > + } else {
> > > + type = MIPI_DSI_DCS_SHORT_WRITE;
> > > + data1 = 0;
> > > + }
> > > +
> > > + reg_val = (data1 << 24) | (data0 << 16) | (type << 8) | config;
> > > +
> > > + writel(reg_val, dsi->regs + DSI_CMDQ0);
> > > + mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, 1);
> > > + }
> > > +}
> > > +

[snip...]

> > 
> > Regards,
> > CK
> > 
> 
> 

Regards,
CK



Re: [PATCH v3 2/2] drm/mediatek: set mt8173 dithering function

2016-07-20 Thread CK Hu
Hi, Bibby:

On Thu, 2016-07-21 at 11:21 +0800, Bibby Hsieh wrote:
> Hi, CK
> 
> I'm appreciate your comments.
> 
> 

[snip...]

> > >  
> > > @@ -469,7 +484,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct 
> > > mtk_ddp_comp *ovl)
> > >   if (state->pending_config) {
> > >   mtk_ddp_comp_config(ovl, state->pending_width,
> > >   state->pending_height,
> > > - state->pending_vrefresh);
> > > + state->pending_vrefresh, 0);
> > 
> > Why set bpc as 0 here? Maybe you have a assumption that OVL don't care
> > the bpc parameter. If one day OVL care it and we do not review here, the
> > bugs happen.
> > 
> Pass 0 means don't care, I will modify mtk_od_config() and
> mtk_gamma_config() to filter this condition.

Using 0 as 'don't care' looks tricky. Please add comments to describe
this.

> > >  
> > >   state->pending_config = false;
> > >   }

Regards,
CK




Re: [PATCH v3 2/2] drm/mediatek: set mt8173 dithering function

2016-07-17 Thread CK Hu
Hi, Bibby:

Some comments inline.

On Thu, 2016-07-07 at 15:37 +0800, Bibby Hsieh wrote:
> Some panels only accept bpc (bit per color) 6-bit.
> But, the default bpc in mt8173 display data path is 8-bit.
> If we didn't enable dithering function to convert bpc,
> display cannot show the smooth grayscale image.
> 
> In mt8173, the dithering function in OD (OverDrive) and
> GAMMA module, we have to config them with
> connector->display_mode.bpc when CRTC initial.
> 
> 1. Clear the default value at *_DITHER_5 and *_DITHER_7 register.
> 2. Calculate the LSB_ERR_SHIFT bits and ADD_LSHIFT bits two values.
> i.e. Input bpc of OD is 10 bits, we assume the bpc of panel is 6-bit,
> so, we need to set 4-bit to LSB_ERR_SHIFT and ADD_LSHIFT bits respectively.
> 3. Then, set the OD or GAMMA to dithering mode depends on path-1 or path-2.
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |3 +-
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|3 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |   21 ++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   77 
> +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |6 +--
>  5 files changed, 92 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 8f62671f..019b7ca 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -103,7 +103,8 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
>  }
>  
>  static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
> -unsigned int h, unsigned int vrefresh)
> +unsigned int h, unsigned int vrefresh,
> +unsigned int bpc)
>  {
>   if (w != 0 && h != 0)
>   writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 5fb80cb..0df05f9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -106,7 +106,8 @@ static void mtk_rdma_stop(struct mtk_ddp_comp *comp)
>  }
>  
>  static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
> - unsigned int height, unsigned int vrefresh)
> + unsigned int height, unsigned int vrefresh,
> + unsigned int bpc)
>  {
>   unsigned int threshold;
>   unsigned int reg;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index ee219bb..18c9d0d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -222,7 +222,9 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc 
> *mtk_crtc)
>  static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
>  {
>   struct drm_crtc *crtc = _crtc->base;
> - unsigned int width, height, vrefresh;
> + struct drm_connector *connector;
> + struct drm_encoder *encoder;
> + unsigned int width, height, vrefresh, bpc = 0;
>   int ret;
>   int i;
>  
> @@ -234,6 +236,19 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc 
> *mtk_crtc)
>   height = crtc->state->adjusted_mode.vdisplay;
>   vrefresh = crtc->state->adjusted_mode.vrefresh;
>  
> + drm_for_each_encoder(encoder, crtc->dev) {
> + if (encoder->crtc != crtc)
> + continue;
> +
> + drm_for_each_connector(connector, crtc->dev) {
> + if (connector->encoder != encoder)
> + continue;
> + if (connector->display_info.bpc >= 3 &&

I think you should left this HW constrain in mtk_od_config() and
mtk_gamma_config(). Here just calculate the expected bpc.

> + (bpc == 0 || bpc > connector->display_info.bpc))

I think bpc should be initialized as HW default bpc and you can remove
this condiction 'bpc == 0' because we should set bpc to HW default bpc
while all connnector bpc is greater than HW default bpc.

> + bpc = connector->display_info.bpc;
> + }
> + }
> +
>   ret = pm_runtime_get_sync(crtc->dev->dev);
>   if (ret < 0) {
>   DRM_ERROR("Failed to enable power domain: %d\n", ret);
> @@ -266,7 +281,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc 
> *mtk_crtc)
>   for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
>   struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
>  
> - mtk_ddp_comp_config(comp, width, height, vrefresh);
> + mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
>   mtk_ddp_comp_start(comp);
>   }
>  
> @@ -469,7 +484,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct 
> mtk_ddp_comp *ovl)
>   if 

Re: [PATCH v4 5/8] drm/mediatek: add dsi interrupt control

2016-07-18 Thread CK Hu
Hi, YT:

Some comments inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi interrupt control
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  130 
> 
>  1 file changed, 130 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 2d808e5..de5ad7f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -32,6 +33,13 @@
>  
>  #define DSI_START0x00
>  
> +#define DSI_INTEN0x08
> +
> +#define DSI_INTSTA   0x0c
> +#define LPRX_RD_RDY_INT_FLAG BIT(0)
> +#define CMD_DONE_INT_FLAGBIT(1)
> +#define DSI_BUSY BIT(31)

Why need LPRX_RD_RDY_INT_FLAG, CMD_DONE_INT_FLAG, and DSI_BUSY? Maybe
these three should be moved to other patch.

> +
>  #define DSI_CON_CTRL 0x10
>  #define DSI_RESETBIT(0)
>  #define DSI_EN   BIT(1)
> @@ -74,6 +82,9 @@
>  
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RACK 0x84
> +#define RACK BIT(0)
> +
>  #define DSI_PHY_LCCON0x104
>  #define LC_HS_TX_EN  BIT(0)
>  #define LC_ULPM_EN   BIT(1)
> @@ -134,6 +145,18 @@ struct mtk_dsi {
>   struct videomode vm;
>   int refcount;
>   bool enabled;
> + int irq_num, irq_data;
> +};
> +
> +enum {
> + DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
> + DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
> + DSI_INT_EXT_TE_RDY_FLAG = BIT(4),
> + DSI_INT_VM_DONE_FLAG= BIT(3),
> + DSI_INT_TE_RDY_FLAG = BIT(2),
> + DSI_INT_CMD_DONE_FLAG   = BIT(1),
> + DSI_INT_LPRX_RD_RDY_FLAG= BIT(0),
> + DSI_INT_ALL_BITS= (0x7f)
>  };

I think you should use '#define' instead of 'enum'. The code would be
like below, and these definition should be moved to after DSI_INTEN or
DSI_INTSTA.

#define DSI_INT_LPRX_RD_RDY_FLAGBIT(0)
#define DSI_INT_CMD_DONE_FLAG   BIT(1)
#define DSI_INT_TE_RDY_FLAG BIT(2)
#define DSI_INT_VM_DONE_FLAGBIT(3)
#define DSI_INT_EXT_TE_RDY_FLAG BIT(4)
#define DSI_INT_VM_CMD_DONE_FLAGBIT(5)
#define DSI_INT_SLEEPOUT_DONE_FLAG  BIT(6)
#define DSI_INT_ALL_BITS(DSI_INT_LPRX_RD_RDY_FLAG | \
DSI_INT_CMD_DONE_FLAG | \
DSI_INT_TE_RDY_FLAG | \
DSI_INT_VM_DONE_FLAG | \
DSI_INT_EXT_TE_RDY_FLAG | \
DSI_INT_VM_CMD_DONE_FLAG | \
DSI_INT_SLEEPOUT_DONE_FLAG)

>  
>  static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
> @@ -440,6 +463,94 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
>   writel(1, dsi->regs + DSI_START);
>  }
>  
> +static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
> +{
> + u32 inten = DSI_INT_ALL_BITS;
> +
> + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO)
> + inten &= ~(DSI_INT_TE_RDY_FLAG | DSI_INT_EXT_TE_RDY_FLAG);
> +
> + writel(inten, dsi->regs + DSI_INTEN);
> +}
> +
> +static void mtk_dsi_irq_wakeup(struct mtk_dsi *dsi, u32 irq_bit)
> +{
> + dsi->irq_data |= irq_bit;
> +}
> +
> +static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
> +{
> + struct mtk_dsi *dsi = dev_id;
> +
> + u32 status, tmp;
> +
> + status = readl(dsi->regs + DSI_INTSTA);
> +
> + if (status & DSI_INT_LPRX_RD_RDY_FLAG) {
> + /* write clear RD_RDY interrupt */
> + /* write clear RD_RDY interrupt must be before DSI_RACK */
> + /* because CMD_DONE will raise after DSI_RACK, */
> + /* so write clear RD_RDY after that will clear CMD_DONE too */
> + do {
> + /* send read ACK */
> + mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
> + tmp = readl(dsi->regs + DSI_INTSTA);
> + } while (tmp & DSI_BUSY);
> +
> + mtk_dsi_mask(dsi, DSI_INTSTA, DSI_INT_LPRX_RD_RDY_FLAG, 0);
> + mtk_dsi_irq_wakeup(dsi, DSI_INT_LPRX_RD_RDY_FLAG);
> + }
> +
> + if (status & DSI_INT_CMD_DONE_FLAG) {
> + mtk_dsi_mask(dsi, DSI_INTSTA, DSI_INT_CMD_DONE_FLAG, 0);
> + mtk_dsi_irq_wakeup(dsi, DSI_INT_CMD_DONE_FLAG);
> + }
> +
> + if (status & DSI_INT_TE_RDY_FLAG) {
> + mtk_dsi_mask(dsi, DSI_INTSTA, DSI_INT_TE_RDY_FLAG, 0);
> + mtk_dsi_irq_wakeup(dsi, DSI_INT_TE_RDY_FLAG);
> + }
> +
> + if (status & DSI_INT_VM_DONE_FLAG) {
> + mtk_dsi_mask(dsi, 

Re: [PATCH 2/4] drm/mediatek: enhance the HDMI driving current

2016-07-20 Thread CK Hu
Hi, Bibby:

One comment inline.

On Wed, 2016-07-20 at 12:03 +0800, Bibby Hsieh wrote:
> From: Junzhi Zhao 
> 
> In order to improve 4K resolution performance,
> we have to enhance the HDMI driving currend
> when clock rate is greater than 165MHz.
> 
> Signed-off-by: Junzhi Zhao 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c |   89 
> +---
>  1 file changed, 63 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c 
> b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> index 8a24754..a871c14 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> @@ -298,32 +298,69 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, 
> unsigned long rate,
> (0x1 << PLL_BR_SHIFT),
> RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
> RG_HDMITX_PLL_BR);
> - mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_PRD_IMP_EN);
> - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
> -   (0x3 << PRD_IBIAS_CLK_SHIFT) |
> -   (0x3 << PRD_IBIAS_D2_SHIFT) |
> -   (0x3 << PRD_IBIAS_D1_SHIFT) |
> -   (0x3 << PRD_IBIAS_D0_SHIFT),
> -   RG_HDMITX_PRD_IBIAS_CLK |
> -   RG_HDMITX_PRD_IBIAS_D2 |
> -   RG_HDMITX_PRD_IBIAS_D1 |
> -   RG_HDMITX_PRD_IBIAS_D0);
> - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
> -   (0x0 << DRV_IMP_EN_SHIFT), RG_HDMITX_DRV_IMP_EN);
> - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
> -   (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
> -   (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
> -   (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
> -   (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT),
> -   RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
> -   RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
> - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
> -   (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) |
> -   (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) |
> -   (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) |
> -   (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT),
> -   RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 |
> -   RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0);
> + if (rate < 16500) {
> + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
> + RG_HDMITX_PRD_IMP_EN);
> + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
> +   (0x3 << PRD_IBIAS_CLK_SHIFT) |
> +   (0x3 << PRD_IBIAS_D2_SHIFT) |
> +   (0x3 << PRD_IBIAS_D1_SHIFT) |
> +   (0x3 << PRD_IBIAS_D0_SHIFT),
> +   RG_HDMITX_PRD_IBIAS_CLK |
> +   RG_HDMITX_PRD_IBIAS_D2 |
> +   RG_HDMITX_PRD_IBIAS_D1 |
> +   RG_HDMITX_PRD_IBIAS_D0);
> + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
> +   (0x0 << DRV_IMP_EN_SHIFT),
> +   RG_HDMITX_DRV_IMP_EN);
> + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
> +   (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
> +   (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
> +   (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
> +   (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT),
> +   RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
> +   RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
> + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
> +   (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) |
> +   (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) |
> +   (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) |
> +   (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT),
> +   RG_HDMITX_DRV_IBIAS_CLK |
> +   RG_HDMITX_DRV_IBIAS_D2 |
> +   RG_HDMITX_DRV_IBIAS_D1 |
> +   RG_HDMITX_DRV_IBIAS_D0);
> + } else {
> + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
> +   RG_HDMITX_PRD_IMP_EN);
> + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
> +   (0x6 << PRD_IBIAS_CLK_SHIFT) |
> +   (0x6 << PRD_IBIAS_D2_SHIFT) 

Re: [PATCH v4 4/8] drm/mediatek: add support for Mediatek SoC MT2701

2016-07-20 Thread CK Hu
Hi, YT:

Some comments inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |6 
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|6 
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   41 
> +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |7 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   31 
>  6 files changed, 92 insertions(+)
> 

[snip...]

>  
>  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> + { .compatible = "mediatek,mt2701-disp-ovl",   .data = (void 
> *)MTK_DISP_OVL },
>   { .compatible = "mediatek,mt8173-disp-ovl",   .data = (void 
> *)MTK_DISP_OVL },
> + { .compatible = "mediatek,mt2701-disp-rdma",  .data = (void 
> *)MTK_DISP_RDMA },
>   { .compatible = "mediatek,mt8173-disp-rdma",  .data = (void 
> *)MTK_DISP_RDMA },
> + { .compatible = "mediatek,mt2701-disp-wdma",  .data = (void 
> *)MTK_DISP_WDMA },

Is WDMA different from MT8173 to MT2701. If they are the same, you need
not to add compatible of 'mediatek,mt2701-disp-wdma' because use
'mediatek,mt8173-disp-wdma' is enough.

>   { .compatible = "mediatek,mt8173-disp-wdma",  .data = (void 
> *)MTK_DISP_WDMA },
> + { .compatible = "mediatek,mt2701-disp-color", .data = (void 
> *)MTK_DISP_COLOR },
>   { .compatible = "mediatek,mt8173-disp-color", .data = (void 
> *)MTK_DISP_COLOR },
>   { .compatible = "mediatek,mt8173-disp-aal",   .data = (void 
> *)MTK_DISP_AAL},
>   { .compatible = "mediatek,mt8173-disp-gamma", .data = (void 
> *)MTK_DISP_GAMMA, },
>   { .compatible = "mediatek,mt8173-disp-ufoe",  .data = (void 
> *)MTK_DISP_UFOE },
> + { .compatible = "mediatek,mt2701-dsi",.data = (void *)MTK_DSI },
>   { .compatible = "mediatek,mt8173-dsi",.data = (void *)MTK_DSI },
> + { .compatible = "mediatek,mt2701-dpi",.data = (void *)MTK_DPI },

Is DPI different from MT8173 to MT2701. If they are the same, you need
not to add compatible of 'mediatek,mt2701-dpi' because use
'mediatek,mt8173-dpi' is enough.

>   { .compatible = "mediatek,mt8173-dpi",.data = (void *)MTK_DPI },
> + { .compatible = "mediatek,mt2701-disp-mutex", .data = (void 
> *)MTK_DISP_MUTEX },
>   { .compatible = "mediatek,mt8173-disp-mutex", .data = (void 
> *)MTK_DISP_MUTEX },
> + { .compatible = "mediatek,mt2701-disp-pwm",   .data = (void 
> *)MTK_DISP_PWM },

Is pwm different from MT8173 to MT2701. If they are the same, you need
not to add compatible of 'mediatek,mt2701-disp-pwm' because use
'mediatek,mt8173-disp-pwm' is enough.

>   { .compatible = "mediatek,mt8173-disp-pwm",   .data = (void 
> *)MTK_DISP_PWM },
>   { .compatible = "mediatek,mt8173-disp-od",.data = (void 
> *)MTK_DISP_OD },
>   { }
> @@ -514,6 +543,8 @@ static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, 
> mtk_drm_sys_suspend,
>mtk_drm_sys_resume);
>  
>  static const struct of_device_id mtk_drm_of_ids[] = {
> + { .compatible = "mediatek,mt2701-mmsys",
> +   .data = _mmsys_driver_data},
>   { .compatible = "mediatek,mt8173-mmsys",
> .data = _mmsys_driver_data},
>   { }

Regards,
CK



Re: [PATCH v4 7/8] drm/mediatek: add mipi panel support

2016-07-20 Thread CK Hu
Hi, YT:

Some comments inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi and mipi tx driver for mipi panel support
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  169 
> ++--
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c |   82 +++-
>  2 files changed, 173 insertions(+), 78 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 1f99894..4eae63c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -29,9 +29,6 @@
>  
>  #include "mtk_drm_ddp_comp.h"
>  
> -#define DSI_VIDEO_FIFO_DEPTH (1920 / 4)
> -#define DSI_HOST_FIFO_DEPTH  64
> -

I think this should be moved to a 'cleaning up and refine' patch.

>  #define DSI_START0x00
>  
>  #define DSI_INTEN0x08
> @@ -55,7 +52,7 @@
>  #define MIX_MODE BIT(17)
>  
>  #define DSI_TXRX_CTRL0x18
> -#define VC_NUM   (2 << 0)
> +#define VC_NUM   BIT(1)

I think this should be moved to a 'cleaning up and refine' patch.

>  #define LANE_NUM (0xf << 2)
>  #define DIS_EOT  BIT(6)
>  #define NULL_EN  BIT(7)
> @@ -94,6 +91,8 @@
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> +#define DSI_MEM_CONTI0x90
> +
>  #define DSI_PHY_LCCON0x104
>  #define LC_HS_TX_EN  BIT(0)
>  #define LC_ULPM_EN   BIT(1)
> @@ -126,6 +125,10 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_VM_CMD_CON   0x130
> +#define VM_CMD_ENBIT(0)
> +#define TS_VFP_ENBIT(5)

The bitwise definition should add one more tab to align other bitwise
definition in this file.

> +
>  #define DSI_CMDQ00x180
>  
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
> @@ -239,11 +242,11 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 
> offset, u32 mask, u32 data)
>   writel((temp & ~mask) | (data & mask), dsi->regs + offset);
>  }
>  
> -static void dsi_phy_timconfig(struct mtk_dsi *dsi)
> +static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)

I think this should be moved to a 'cleaning up and refine' patch.

>  {
>   u32 timcon0, timcon1, timcon2, timcon3;
> - unsigned int ui, cycle_time;
> - unsigned int lpx;
> + u32 ui, cycle_time;
> + u32 lpx;

I think this should be moved to a 'cleaning up and refine' patch.

>  
>   ui = 1000 / dsi->data_rate + 0x01;
>   cycle_time = 8000 / dsi->data_rate + 0x01;
> @@ -273,7 +276,7 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
>  }
>  
> -static void mtk_dsi_reset(struct mtk_dsi *dsi)
> +static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
> @@ -293,7 +296,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>* mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
>* we set mipi_ratio is 1.05.
>*/
> - dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
> + dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
> + dsi->data_rate /= (dsi->lanes * 1000 * 10);
> + dev_info(dev, "set mipitx's data rate: %dMHz\n", dsi->data_rate);
>  
>   ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 100);
>   if (ret < 0) {
> @@ -315,10 +320,6 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>   goto err_disable_engine_clk;
>   }
>  
> - mtk_dsi_enable(dsi);
> - mtk_dsi_reset(dsi);
> - dsi_phy_timconfig(dsi);
> -
>   return 0;
>  
>  err_disable_engine_clk:
> @@ -330,33 +331,33 @@ err_refcount:
>   return ret;
>  }
>  
> -static void dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
> +static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)

I think this should be moved to a 'cleaning up and refine' patch.

>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
> - mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
> + mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, LC_ULPM_EN);
>  }
>  
> -static void dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
> +static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)

I think this should be moved to a 'cleaning up and refine' patch.

>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, LC_WAKEUP_EN);
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, 0);
>  }
>  
> -static void dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
> +static void 

Re: [PATCH 3/4] drm/mediatek: fix the wrong pixel clock when resolution is 4K

2016-07-20 Thread CK Hu
Hi, Bibby:

Some comments inline.

On Wed, 2016-07-20 at 12:03 +0800, Bibby Hsieh wrote:
> From: Junzhi Zhao 
> 
> Pixel clock should be 297MHz when resolution is 4K.
> 
> Signed-off-by: Junzhi Zhao 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c |  184 
> +---
>  1 file changed, 131 insertions(+), 53 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index d05ca79..c0f04d2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -60,14 +60,35 @@ enum mtk_dpi_out_color_format {
>   MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
>  };
>  
> +enum mtk_dpi_clk_id {
> + MTK_DPI_CLK_DPI_ENGINE,
> + MTK_DPI_CLK_DPI_PIXEL,
> + MTK_DPI_CLK_TVD_PLL,
> + MTK_DPI_CLK_TVDPLL_MUX,
> + MTK_DPI_CLK_TVDPLL_D2,
> + MTK_DPI_CLK_TVDPLL_D4,
> + MTK_DPI_CLK_TVDPLL_D8,
> + MTK_DPI_CLK_TVDPLL_D16,
> + MTK_DPI_CLK_COUNT,
> +};
> +
> +static const char * const mtk_dpi_clk_names[MTK_DPI_CLK_COUNT] = {
> + [MTK_DPI_CLK_DPI_ENGINE] = "engine",
> + [MTK_DPI_CLK_DPI_PIXEL] = "pixel",
> + [MTK_DPI_CLK_TVD_PLL] = "pll",
> + [MTK_DPI_CLK_TVDPLL_MUX] = "tvdpll_mux",
> + [MTK_DPI_CLK_TVDPLL_D2] = "tvdpll_d2",
> + [MTK_DPI_CLK_TVDPLL_D4] = "tvdpll_d4",
> + [MTK_DPI_CLK_TVDPLL_D8] = "tvdpll_d8",
> + [MTK_DPI_CLK_TVDPLL_D16] = "tvdpll_d16",
> +};
> +
>  struct mtk_dpi {
>   struct mtk_ddp_comp ddp_comp;
>   struct drm_encoder encoder;
>   void __iomem *regs;
>   struct device *dev;
> - struct clk *engine_clk;
> - struct clk *pixel_clk;
> - struct clk *tvd_clk;
> + struct clk *clk[MTK_DPI_CLK_COUNT];
>   int irq;
>   struct drm_display_mode mode;
>   enum mtk_dpi_out_color_format color_format;
> @@ -76,6 +97,7 @@ struct mtk_dpi {
>   enum mtk_dpi_out_channel_swap channel_swap;
>   bool power_sta;
>   u8 power_ctl;
> + void *data;
>  };
>  
>  static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e)
> @@ -114,6 +136,11 @@ struct mtk_dpi_yc_limit {
>   u16 c_bottom;
>  };
>  
> +struct mtk_dpi_conf {
> + int (*parse_clk_from_dt)(struct mtk_dpi *dpi, struct device_node *np);
> + int (*clk_config)(struct mtk_dpi *dpi, struct drm_display_mode *mode);
> +};
> +
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
>  {
>   u32 tmp = readl(dpi->regs + offset) & ~mask;
> @@ -377,8 +404,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi, enum 
> mtk_dpi_power_ctl pctl)
>   return;
>  
>   mtk_dpi_disable(dpi);
> - clk_disable_unprepare(dpi->pixel_clk);
> - clk_disable_unprepare(dpi->engine_clk);
> + clk_disable_unprepare(dpi->clk[MTK_DPI_CLK_DPI_PIXEL]);
> + clk_disable_unprepare(dpi->clk[MTK_DPI_CLK_DPI_ENGINE]);
>   dpi->power_sta = false;
>  }
>  
> @@ -395,13 +422,13 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum 
> mtk_dpi_power_ctl pctl)
>   if (dpi->power_sta)
>   return 0;
>  
> - ret = clk_prepare_enable(dpi->engine_clk);
> + ret = clk_prepare_enable(dpi->clk[MTK_DPI_CLK_DPI_ENGINE]);
>   if (ret) {
>   dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   goto err_eng;
>   }
>  
> - ret = clk_prepare_enable(dpi->pixel_clk);
> + ret = clk_prepare_enable(dpi->clk[MTK_DPI_CLK_DPI_PIXEL]);
>   if (ret) {
>   dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
>   goto err_pixel;
> @@ -412,7 +439,7 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum 
> mtk_dpi_power_ctl pctl)
>   return 0;
>  
>  err_pixel:
> - clk_disable_unprepare(dpi->engine_clk);
> + clk_disable_unprepare(dpi->clk[MTK_DPI_CLK_DPI_ENGINE]);
>  err_eng:
>   dpi->power_ctl &= ~pctl;
>   return ret;
> @@ -428,34 +455,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   struct mtk_dpi_sync_param vsync_leven = { 0 };
>   struct mtk_dpi_sync_param vsync_rodd = { 0 };
>   struct mtk_dpi_sync_param vsync_reven = { 0 };
> - unsigned long pix_rate;
> - unsigned long pll_rate;
> - unsigned int factor;
> + struct mtk_dpi_conf *conf;
> + int ret;
>  
>   if (!dpi) {
>   dev_err(dpi->dev, "invalid argument\n");
>   return -EINVAL;
>   }
>  
> - pix_rate = 1000UL * mode->clock;
> - if (mode->clock <= 74000)
> - factor = 8 * 3;
> - else
> - factor = 4 * 3;
> - pll_rate = pix_rate * factor;
> -
> - dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
> - pll_rate, pix_rate);
> -
> - clk_set_rate(dpi->tvd_clk, pll_rate);
> - pll_rate = clk_get_rate(dpi->tvd_clk);
> -
> - pix_rate = pll_rate / factor;
> - clk_set_rate(dpi->pixel_clk, pix_rate);
> -   

Re: [PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-20 Thread CK Hu
Hi, YT:

Some comments inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
> 
>  1 file changed, 322 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index de5ad7f..1f99894 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -80,8 +81,16 @@
>  #define DSI_HBP_WC   0x54
>  #define DSI_HFP_WC   0x58
>  
> +#define DSI_CMDQ_SIZE0x60
> +#define CMDQ_SIZE0x3f
> +
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RX_DATA0 0x74
> +#define DSI_RX_DATA1 0x78
> +#define DSI_RX_DATA2 0x7c
> +#define DSI_RX_DATA3 0x80
> +
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> @@ -117,8 +126,25 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_CMDQ00x180
> +
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
> +#define MTK_DSI_HOST_IS_READ(type) \
> + ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> + (type == MIPI_DSI_DCS_READ))
> +
> +#define MTK_DSI_HOST_IS_WRITE(type) \
> + ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> + (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> + (type == MIPI_DSI_DCS_LONG_WRITE))
> +
>  struct phy;
>  
>  struct mtk_dsi {
> @@ -148,6 +174,38 @@ struct mtk_dsi {
>   int irq_num, irq_data;
>  };
>  
> +struct dsi_cmd_t0 {
> + u8 config;
> + u8 type;
> + u8 data0;
> + u8 data1;
> +};
> +
> +struct dsi_cmd_t2 {
> + u8 config;
> + u8 type;
> + u16 wc16;
> + u8 *pdata;
> +};
> +
> +struct dsi_rx_data {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq_regs {
> + struct dsi_tx_cmdq data[128];
> +};
> +
>  enum {
>   DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
>   DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
> @@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return 0;
>  }
>  
> +static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
> +{
> + u32 temp = readl(reg);
> +
> + writel((temp & ~mask) | (data & mask), reg);
> +}
> +
> +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> +{
> + u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> +
> + while (timeout_ms--) {
> + if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> + break;
> +
> + usleep_range(2, 4);
> + }
> +
> + if (timeout_ms == 0) {
> + dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
> +  const struct mipi_dsi_msg *msg)
> +{
> + u8 max_try_count = 5;
> + u32 recv_data_cnt, tmp_val;
> + u32 recv_data0, recv_data1, recv_data2, recv_data3;
> + struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
> + struct dsi_cmd_t0 t0;
> + s32 ret;
> +
> + u8 *buffer = msg->rx_buf;
> + u8 buffer_size = msg->rx_len;
> + u8 packet_type;
> +
> + if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
> + dev_info(dsi->dev, "dsi engine is not command mode\n");
> + return -1;
> + }
> +
> + if (!buffer) {
> + dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
> + return -1;
> + }
> +
> + do {
> + if (max_try_count == 0) {
> + dev_info(dsi->dev, "dsi engine read counter has been 
> maxinum\n");
> + return -1;
> + }
> +
> + max_try_count--;
> + recv_data_cnt = 0;
> +
> + mtk_dsi_wait_for_idle(dsi);
> +
> + t0.config = 0x04;
> + t0.data0 = *((u8 *)(msg->tx_buf));
> +
> + if (buffer_size < 0x3)

It's better to use '3' instead of '0x3'.

> + t0.type = MIPI_DSI_DCS_READ;
> + 

Re: [PATCH v3 1/2] drm/mediatek: Add gamma correction

2016-07-15 Thread CK Hu
Hi, Bibby:

Some comments inline.

On Thu, 2016-07-07 at 15:37 +0800, Bibby Hsieh wrote:
> Apply gamma function to correct brightness values.
> It applies arbitrary mapping curve to compensate the
> incorrect transfer function of the panel.
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |8 +++
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   89 
> ++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   10 +++
>  4 files changed, 106 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 24aa3ba..ee219bb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -409,6 +409,10 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
>   }
>   if (pending_planes)
>   mtk_crtc->pending_planes = true;
> + if (crtc->state->color_mgmt_changed)
> + for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
> + mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
> +
>  }
>  
>  static const struct drm_crtc_funcs mtk_crtc_funcs = {
> @@ -418,6 +422,7 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
>   .reset  = mtk_drm_crtc_reset,
>   .atomic_duplicate_state = mtk_drm_crtc_duplicate_state,
>   .atomic_destroy_state   = mtk_drm_crtc_destroy_state,
> + .gamma_set  = drm_atomic_helper_legacy_gamma_set,
>  };
>  
>  static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
> @@ -569,6 +574,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>   if (ret < 0)
>   goto unprepare;
>  
> + drm_mode_crtc_set_gamma_size(_crtc->base, MTK_LUT_SIZE);
> + drm_helper_crtc_enable_color_mgmt(_crtc->base, MTK_LUT_SIZE,
> +   MTK_LUT_SIZE);
>   priv->crtc[pipe] = _crtc->base;
>   priv->num_pipes++;
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> index 81e5566..d332564 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> @@ -19,6 +19,7 @@
>  #include "mtk_drm_plane.h"
>  
>  #define OVL_LAYER_NR 4
> +#define MTK_LUT_SIZE 512
>  
>  int mtk_drm_crtc_enable_vblank(struct drm_device *drm, unsigned int pipe);
>  void mtk_drm_crtc_disable_vblank(struct drm_device *drm, unsigned int pipe);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 3970fcf..56c5894 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -24,6 +24,7 @@
>  #include "mtk_drm_drv.h"
>  #include "mtk_drm_plane.h"
>  #include "mtk_drm_ddp_comp.h"
> +#include "mtk_drm_crtc.h"
>  
>  #define DISP_OD_EN   0x
>  #define DISP_OD_INTEN0x0008
> @@ -38,6 +39,21 @@
>  #define DISP_COLOR_WIDTH 0x0c50
>  #define DISP_COLOR_HEIGHT0x0c54
>  
> +#define DISP_AAL_EN  0x000
> +#define DISP_AAL_SIZE0x030
> +
> +#define DISP_GAMMA_EN0x000
> +#define DISP_GAMMA_CFG   0x020
> +#define DISP_GAMMA_SIZE  0x030
> +#define DISP_GAMMA_LUT   0x700

It's better that the digits of register address of OD, COLOR, AAL, and
GAMMA are the same. Maybe you can align all to 4 digits.

> +
> +#define LUT_10BIT_MASK   0x3ff
> +
> +#define AAL_EN   BIT(0)
> +
> +#define GAMMA_EN BIT(0)
> +#define GAMMA_LUT_EN BIT(1)
> +
>  #define  OD_RELAY_MODE   BIT(0)
>  
>  #define  UFO_BYPASS  BIT(2)
> @@ -76,6 +92,61 @@ static void mtk_ufoe_start(struct mtk_ddp_comp *comp)
>   writel(UFO_BYPASS, comp->regs + DISP_REG_UFO_START);
>  }
>  
> +static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w,
> +unsigned int h, unsigned int vrefresh)
> +{
> + writel(h << 16 | w, comp->regs + DISP_AAL_SIZE);
> +}
> +
> +static void mtk_aal_start(struct mtk_ddp_comp *comp)
> +{
> + writel(AAL_EN, comp->regs  + DISP_AAL_EN);
> +}
> +
> +static void mtk_aal_stop(struct mtk_ddp_comp *comp)
> +{
> + writel_relaxed(0x0, comp->regs  + DISP_AAL_EN);
> +}

I think AAL is somewhat different from GAMMA and this patch include 3
modifications:

1. AAL basic config
2. GAMMA basic config
3. Add gamma function of AAL and GAMMA

So you should split this patch into 3 patches.

> +
> +static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w,
> +  unsigned int h, unsigned int vrefresh)
> +{
> + writel(h 

Re: [PATCH v4 3/8] drm/mediatek: add shadow register support

2016-07-18 Thread CK Hu
Hi, YT:

One comment inline.


On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> We need to acquire mutex before using the resources,
> and need to release it after finished.
> So we don't need to write registers in the blanking period.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |   75 
> +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   22 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |2 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |1 +
>  4 files changed, 71 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 24aa3ba..80d9641 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -315,6 +315,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
> *mtk_crtc)
>   pm_runtime_put(drm->dev);
>  }
>  
> +static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
> +{
> + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> + struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
> + unsigned int i;
> +
> + /*
> +  * TODO: instead of updating the registers here, we should prepare
> +  * working registers in atomic_commit and let the hardware command
> +  * queue update module registers on vblank.
> +  */
> + if (state->pending_config) {
> + mtk_ddp_comp_config(ovl, state->pending_width,
> + state->pending_height,
> + state->pending_vrefresh);
> +
> + state->pending_config = false;
> + }
> +
> + if (mtk_crtc->pending_planes) {
> + for (i = 0; i < OVL_LAYER_NR; i++) {
> + struct drm_plane *plane = _crtc->planes[i].base;
> + struct mtk_plane_state *plane_state;
> +
> + plane_state = to_mtk_plane_state(plane->state);
> +
> + if (plane_state->pending.config) {
> + mtk_ddp_comp_layer_config(ovl, i, plane_state);
> + plane_state->pending.config = false;
> + }
> + }
> + mtk_crtc->pending_planes = false;
> + }
> +}
> +
>  static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> @@ -391,6 +427,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
> struct drm_crtc_state *old_crtc_state)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_drm_private *priv = crtc->dev->dev_private;
>   unsigned int pending_planes = 0;
>   int i;
>  
> @@ -409,6 +446,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
>   }
>   if (pending_planes)
>   mtk_crtc->pending_planes = true;
> +
> + if (priv->data->shadow_register) {
> + mtk_disp_mutex_acquire(mtk_crtc->mutex);
> + mtk_crtc_ddp_config(crtc);
> + mtk_disp_mutex_release(mtk_crtc->mutex);
> + }
>  }
>  
>  static const struct drm_crtc_funcs mtk_crtc_funcs = {
> @@ -453,36 +496,10 @@ err_cleanup_crtc:
>  void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> - struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> - unsigned int i;
> + struct mtk_drm_private *priv = crtc->dev->dev_private;
>  
> - /*
> -  * TODO: instead of updating the registers here, we should prepare
> -  * working registers in atomic_commit and let the hardware command
> -  * queue update module registers on vblank.
> -  */
> - if (state->pending_config) {
> - mtk_ddp_comp_config(ovl, state->pending_width,
> - state->pending_height,
> - state->pending_vrefresh);
> -
> - state->pending_config = false;
> - }
> -
> - if (mtk_crtc->pending_planes) {
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = _crtc->planes[i].base;
> - struct mtk_plane_state *plane_state;
> -
> - plane_state = to_mtk_plane_state(plane->state);
> -
> - if (plane_state->pending.config) {
> - mtk_ddp_comp_layer_config(ovl, i, plane_state);
> - plane_state->pending.config = false;
> - }
> - }
> - mtk_crtc->pending_planes = false;
> - }
> + if (!priv->data->shadow_register)
> + mtk_crtc_ddp_config(crtc);
>  
>   mtk_drm_finish_page_flip(mtk_crtc);
>  }
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> 

Re: [PATCH v4 4/8] drm/mediatek: add support for Mediatek SoC MT2701

2016-07-18 Thread CK Hu
Hi, YT:

One comment inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |6 
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|6 
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   41 
> +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |7 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   31 
>  6 files changed, 92 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index eb5c05e..1da0a71 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -286,11 +286,17 @@ static int mtk_disp_ovl_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_ddp_comp_driver_data mt2701_ovl_driver_data = {
> + .ovl = {0x0040, 1 << 12, 0}
> +};
> +
>  static const struct mtk_ddp_comp_driver_data mt8173_ovl_driver_data = {
>   .ovl = {0x0f40, 0, 1 << 12}
>  };
>  
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-ovl",
> +   .data = _ovl_driver_data},
>   { .compatible = "mediatek,mt8173-disp-ovl",
> .data = _ovl_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index fb0db50..506a353 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -225,11 +225,17 @@ static int mtk_disp_rdma_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_ddp_comp_driver_data mt2701_rdma_driver_data = {
> + .rdma_fifo_pseudo_size = SZ_4K,
> +};
> +
>  static const struct mtk_ddp_comp_driver_data mt8173_rdma_driver_data = {
>   .rdma_fifo_pseudo_size = SZ_8K,
>  };
>  
>  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-rdma",
> +   .data = _rdma_driver_data},
>   { .compatible = "mediatek,mt8173-disp-rdma",
> .data = _rdma_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index fa53806..ee0326a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -32,6 +32,10 @@
>  #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN   0x0c8
>  #define DISP_REG_CONFIG_MMSYS_CG_CON00x100
>  
> +#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030
> +#define DISP_REG_CONFIG_OUT_SEL  0x04c
> +#define DISP_REG_CONFIG_DSI_SEL  0x050
> +
>  #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
>  #define DISP_REG_MUTEX(n)(0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)(0x28 + 0x20 * (n))
> @@ -54,6 +58,13 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1   BIT(24)
>  #define MT8173_MUTEX_MOD_DISP_OD BIT(25)
>  
> +#define MT2701_MUTEX_MOD_DISP_OVLBIT(3)
> +#define MT2701_MUTEX_MOD_DISP_WDMA   BIT(6)
> +#define MT2701_MUTEX_MOD_DISP_COLOR  BIT(7)
> +#define MT2701_MUTEX_MOD_DISP_BLSBIT(9)
> +#define MT2701_MUTEX_MOD_DISP_RDMA0  BIT(10)
> +#define MT2701_MUTEX_MOD_DISP_RDMA1  BIT(12)
> +
>  #define MUTEX_SOF_SINGLE_MODE0
>  #define MUTEX_SOF_DSI0   1
>  #define MUTEX_SOF_DSI1   2
> @@ -69,6 +80,10 @@
>  #define DPI0_SEL_IN_RDMA10x1
>  #define COLOR1_SEL_IN_OVL1   0x1
>  
> +#define OVL_MOUT_EN_RDMA 0x1
> +#define BLS_TO_DSI_RDMA1_TO_DPI1 0x8
> +#define DSI_SEL_IN_BLS   0x0
> +
>  struct mtk_disp_mutex {
>   int id;
>   bool claimed;
> @@ -82,6 +97,15 @@ struct mtk_ddp {
>   const unsigned int  *mutex_mod;
>  };
>  
> +static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> + [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
> + [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
> + [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
> + [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
> + [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
> + [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
> +};
> +
>  static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
>   [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
> @@ -109,6 +133,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id 
> cur,
>   if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
>   *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;

[PATCH] drm: mediatek: add Maintainers entry for Mediatek DRM drivers

2016-07-14 Thread CK Hu
Add CK Hu and Philipp Zabel as maintainers for Mediatek DRM drivers.

Signed-off-by: CK Hu <ck...@mediatek.com>
---
 MAINTAINERS |8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7304d2e..2a04cdc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3973,6 +3973,14 @@ S:   Orphan / Obsolete
 F: drivers/gpu/drm/i810/
 F: include/uapi/drm/i810_drm.h
 
+DRM DRIVERS FOR MEDIATEK
+M:     CK Hu <ck...@mediatek.com>
+M: Philipp Zabel <p.za...@pengutronix.de>
+L: dri-de...@lists.freedesktop.org
+S: Supported
+F: drivers/gpu/drm/mediatek/
+F: Documentation/devicetree/bindings/display/mediatek/
+
 DRM DRIVER FOR MSM ADRENO GPU
 M: Rob Clark <robdcl...@gmail.com>
 L: linux-arm-...@vger.kernel.org
-- 
1.7.9.5



Re: [PATCH v6 09/10] drm/mediatek: add support for Mediatek SoC MT2701

2016-08-05 Thread CK Hu
Hi, YT:

On Thu, 2016-08-04 at 19:07 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |6 ++
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|6 ++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  |   17 +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |7 ++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   29 +
>  drivers/gpu/drm/mediatek/mtk_dsi.c  |1 +
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c  |   31 
> ++-
>  8 files changed, 97 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index eb5c05e..1da0a71 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -286,11 +286,17 @@ static int mtk_disp_ovl_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_ddp_comp_driver_data mt2701_ovl_driver_data = {
> + .ovl = {0x0040, 1 << 12, 0}
> +};
> +
>  static const struct mtk_ddp_comp_driver_data mt8173_ovl_driver_data = {
>   .ovl = {0x0f40, 0, 1 << 12}
>  };
>  
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-ovl",
> +   .data = _ovl_driver_data},
>   { .compatible = "mediatek,mt8173-disp-ovl",
> .data = _ovl_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index fb0db50..506a353 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -225,11 +225,17 @@ static int mtk_disp_rdma_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_ddp_comp_driver_data mt2701_rdma_driver_data = {
> + .rdma_fifo_pseudo_size = SZ_4K,
> +};
> +
>  static const struct mtk_ddp_comp_driver_data mt8173_rdma_driver_data = {
>   .rdma_fifo_pseudo_size = SZ_8K,
>  };
>  
>  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-rdma",
> +   .data = _rdma_driver_data},
>   { .compatible = "mediatek,mt8173-disp-rdma",
> .data = _rdma_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index a9b209c..8130f3d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -60,6 +60,13 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1   BIT(24)
>  #define MT8173_MUTEX_MOD_DISP_OD BIT(25)
>  
> +#define MT2701_MUTEX_MOD_DISP_OVLBIT(3)
> +#define MT2701_MUTEX_MOD_DISP_WDMA   BIT(6)
> +#define MT2701_MUTEX_MOD_DISP_COLOR  BIT(7)
> +#define MT2701_MUTEX_MOD_DISP_BLSBIT(9)
> +#define MT2701_MUTEX_MOD_DISP_RDMA0  BIT(10)
> +#define MT2701_MUTEX_MOD_DISP_RDMA1  BIT(12)
> +
>  #define MUTEX_SOF_SINGLE_MODE0
>  #define MUTEX_SOF_DSI0   1
>  #define MUTEX_SOF_DSI1   2
> @@ -92,6 +99,15 @@ struct mtk_ddp {
>   const unsigned int  *mutex_mod;
>  };
>  
> +static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> + [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
> + [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
> + [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
> + [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
> + [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
> + [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
> +};
> +
>  static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
>   [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
> @@ -390,6 +406,7 @@ static int mtk_ddp_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id ddp_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-mutex", .data = mt2701_mutex_mod},
>   { .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod},
>   {},
>  };
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 4b4e449..465819b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -112,6 +112,7 @@ struct mtk_ddp_comp_match {
>  
>  static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] 
> = {
>   [DDP_COMPONENT_AAL] = { MTK_DISP_AAL,   0, NULL },
> + [DDP_COMPONENT_BLS] = { MTK_DISP_PWM,   0, NULL },
>   [DDP_COMPONENT_COLOR0]  = { 

Re: [PATCH v6 10/10] arm: dts: mt2701: Add display subsystem related nodes for MT2701

2016-08-05 Thread CK Hu
Hi, YT:

On Thu, 2016-08-04 at 19:07 +0800, YT Shen wrote:
> This patch adds the device nodes for the DISP function blocks for MT2701
> 
> Signed-off-by: YT Shen 
> ---
>  arch/arm/boot/dts/mt2701.dtsi |   86 
> +
>  1 file changed, 86 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index f3136bd..8f35a0d 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -24,6 +24,11 @@
>   compatible = "mediatek,mt2701";
>   interrupt-parent = <>;
>  
> + aliases {
> + rdma0 = 
> + rdma1 = 
> + };
> +
>   cpus {
>   #address-cells = <1>;
>   #size-cells = <0>;
> @@ -171,6 +176,16 @@
>   power-domains = < MT2701_POWER_DOMAIN_DISP>;
>   };
>  
> + mipi_tx0: mipi-dphy@1001 {
> + compatible = "mediatek,mt2701-mipi-tx";
> + reg = <0 0x1001 0 0x90>;
> + clocks = <>;
> + clock-output-names = "mipi_tx0_pll";
> + #clock-cells = <0>;
> + #phy-cells = <0>;
> + status = "disabled";
> + };
> +
>   sysirq: interrupt-controller@10200100 {
>   compatible = "mediatek,mt2701-sysirq",
>"mediatek,mt6577-sysirq";
> @@ -255,6 +270,68 @@
>   status = "disabled";
>   };
>  
> + ovl@14007000 {
> + compatible = "mediatek,mt2701-disp-ovl";
> + reg = <0 0x14007000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DISP_OVL>;
> + iommus = < MT2701_M4U_PORT_DISP_OVL_0>;
> + mediatek,larb = <>;
> + };
> +
> + rdma0: rdma@14008000 {
> + compatible = "mediatek,mt2701-disp-rdma";
> + reg = <0 0x14008000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DISP_RDMA>;
> + iommus = < MT2701_M4U_PORT_DISP_RDMA>;
> + mediatek,larb = <>;
> + };
> +
> + wdma@14009000 {
> + compatible = "mediatek,mt2701-disp-wdma";
> + reg = <0 0x14009000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DISP_WDMA>;
> + iommus = < MT2701_M4U_PORT_DISP_WDMA>;
> + mediatek,larb = <>;
> + };
> +
> + bls@1400a000 {
> + compatible = "mediatek,mt2701-disp-pwm";
> + reg = <0 0x1400a000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DISP_BLS>;
> + };

You depends on [1], but that series include [2] which also add a
disp_bls node which has the same compatible string
"mediatek,mt2701-disp-pwm". If these two node are the same, just add it
in one patch. If they are different, do not use the same compatible
string.

[1] https://patchwork.kernel.org/patch/9222997/ ("dt-bindings: pwm: Add
MediaTek display PWM bindings")
[2] https://patchwork.kernel.org/patch/9223005/
> +
> + color@1400b000 {
> + compatible = "mediatek,mt2701-disp-color";
> + reg = <0 0x1400b000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DISP_COLOR>;
> + };
> +
> + dsi0: dsi@1400c000 {
> + compatible = "mediatek,mt2701-dsi";
> + reg = <0 0x1400c000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DSI_ENGINE>, < CLK_MM_DSI_DIG>,
> +  <_tx0>;
> + clock-names = "engine", "digital", "hs";
> + mediatek,syscon-dsi = < 0x138>;
> + mediatek,ssc-range = <5>;
> + phys = <_tx0>;
> + phy-names = "dphy";
> + status = "disabled";
> + };
> +
> + mutex: mutex@1400e000 {
> + compatible = "mediatek,mt2701-disp-mutex";
> + reg = <0 0x1400e000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_MUTEX_32K>;
> + };
> +
>   larb0: larb@1401 {
>   compatible = "mediatek,mt2701-smi-larb";
>   reg = <0 0x1401 0 0x1000>;
> @@ -266,6 +343,15 @@
>   power-domains = < MT2701_POWER_DOMAIN_DISP>;
>   };
>  
> + rdma1: rdma@14012000 {
> + compatible = "mediatek,mt2701-disp-rdma";
> + reg = <0 0x14012000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_MM_DISP_RDMA1>;
> + iommus = < MT2701_M4U_PORT_DISP_RDMA1>;
> + mediatek,larb = <>;
> + };
> +
>   imgsys: syscon@1500 {
>   compatible = "mediatek,mt2701-imgsys", "syscon";
>   reg = <0 0x1500 0 0x1000>;

Regards,
CK



Re: [PATCH v6 06/10] drm/mediatek: add dsi interrupt control

2016-08-05 Thread CK Hu
Hi, YT:

On Thu, 2016-08-04 at 19:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi interrupt control
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |   76 
> 
>  1 file changed, 76 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a9cf5a1..eea6192 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -29,6 +30,17 @@
>  
>  #define DSI_START0x00
>  
> +#define DSI_INTEN0x08
> +
> +#define DSI_INTSTA   0x0c
> +#define LPRX_RD_RDY_INT_FLAG BIT(0)
> +#define CMD_DONE_INT_FLAGBIT(1)
> +#define TE_RDY_INT_FLAG  BIT(2)
> +#define VM_DONE_INT_FLAG BIT(3)
> +#define EXT_TE_RDY_INT_FLAG  BIT(4)
> +#define DSI_INT_ALL_BITS 0x1f
> +#define DSI_BUSY BIT(31)
> +
>  #define DSI_CON_CTRL 0x10
>  #define DSI_RESETBIT(0)
>  #define DSI_EN   BIT(1)
> @@ -71,6 +83,9 @@
>  
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RACK 0x84
> +#define RACK BIT(0)
> +
>  #define DSI_PHY_LCCON0x104
>  #define LC_HS_TX_EN  BIT(0)
>  #define LC_ULPM_EN   BIT(1)
> @@ -131,8 +146,11 @@ struct mtk_dsi {
>   struct videomode vm;
>   int refcount;
>   bool enabled;
> + int irq_data;

u32 irq_data;

>  };
>  
> +static wait_queue_head_t _dsi_irq_wait_queue;
> +
>  static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
>  {
>   return container_of(e, struct mtk_dsi, encoder);
> @@ -437,6 +455,43 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
>   writel(1, dsi->regs + DSI_START);
>  }
>  
> +static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
> +{
> + u32 inten = DSI_INT_ALL_BITS;
> +
> + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO)
> + inten &= ~(TE_RDY_INT_FLAG | EXT_TE_RDY_INT_FLAG);
> +
> + writel(inten, dsi->regs + DSI_INTEN);
> +}
> +
> +static void mtk_dsi_irq_wakeup(struct mtk_dsi *dsi, u32 irq_bit)
> +{
> + dsi->irq_data |= irq_bit;
> +}
> +
> +static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
> +{
> + struct mtk_dsi *dsi = dev_id;
> + u32 status, tmp;
> + u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
> +
> + status = readl(dsi->regs + DSI_INTSTA);
> +
> + if (status & flag) {
> + do {
> + mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
> + tmp = readl(dsi->regs + DSI_INTSTA);
> + } while (tmp & DSI_BUSY);
> +
> + mtk_dsi_mask(dsi, DSI_INTSTA, status & flag, 0);
> + mtk_dsi_irq_wakeup(dsi, status & flag);
> + wake_up_interruptible(&_dsi_irq_wait_queue);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
>  static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  {
>   if (WARN_ON(dsi->refcount == 0))
> @@ -485,6 +540,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>  
>   mtk_dsi_ps_control_vact(dsi);
>   mtk_dsi_config_vdo_timing(dsi);
> + mtk_dsi_set_interrupt_enable(dsi);
>  
>   mtk_dsi_set_mode(dsi);
>   mtk_dsi_clk_hs_mode(dsi, 1);
> @@ -804,6 +860,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   struct device *dev = >dev;
>   struct device_node *remote_node, *endpoint;
>   struct resource *regs;
> + int irq_num;
>   int comp_id;
>   int ret;
>  
> @@ -880,8 +937,27 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   return ret;
>   }
>  
> + irq_num = platform_get_irq(pdev, 0);
> + if (irq_num < 0) {
> + dev_err(>dev, "failed to request dsi irq resource\n");
> + return -EPROBE_DEFER;
> + }
> +
> + irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
> + ret = devm_request_irq(>dev, irq_num, mtk_dsi_irq,
> +IRQF_TRIGGER_LOW, dev_name(>dev), dsi);
> + if (ret) {
> + dev_err(>dev, "failed to request mediatek dsi irq\n");
> + return -EPROBE_DEFER;
> + }
> +
> + dsi->irq_data = 0;
> + dev_info(dev, "dsi irq num is 0x%x\n", irq_num);
> +
>   platform_set_drvdata(pdev, dsi);
>  
> + init_waitqueue_head(&_dsi_irq_wait_queue);
> +
>   return component_add(>dev, _dsi_component_ops);
>  }
>  

Regards,
CK



Re: [PATCH v6 07/10] drm/mediatek: add dsi transfer function

2016-08-05 Thread CK Hu
Hi, YT:

On Thu, 2016-08-04 at 19:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  261 
> 
>  1 file changed, 261 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index eea6192..4541f59 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -81,8 +82,16 @@
>  #define DSI_HBP_WC   0x54
>  #define DSI_HFP_WC   0x58
>  
> +#define DSI_CMDQ_SIZE0x60
> +#define CMDQ_SIZE0x3f
> +
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RX_DATA0 0x74
> +#define DSI_RX_DATA1 0x78
> +#define DSI_RX_DATA2 0x7c
> +#define DSI_RX_DATA3 0x80
> +
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> @@ -118,8 +127,25 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_CMDQ00x180
> +
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
> +#define MTK_DSI_HOST_IS_READ(type) \
> + ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> + (type == MIPI_DSI_DCS_READ))
> +
> +#define MTK_DSI_HOST_IS_WRITE(type) \
> + ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> + (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> + (type == MIPI_DSI_DCS_LONG_WRITE))
> +
>  struct phy;
>  
>  struct mtk_dsi {
> @@ -149,6 +175,13 @@ struct mtk_dsi {
>   int irq_data;
>  };
>  
> +struct dsi_rxtx_data {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
>  static wait_queue_head_t _dsi_irq_wait_queue;
>  
>  static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
> @@ -799,9 +832,237 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return 0;
>  }
>  
> +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> +{
> + u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> +
> + while (timeout_ms--) {
> + if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> + break;
> +
> + usleep_range(2, 4);
> + }
> +
> + if (timeout_ms == 0) {
> + dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static void mtk_dsi_wait_for_cmd_done(struct mtk_dsi *dsi)
> +{
> + s32 ret = 0;
> + unsigned long timeout = msecs_to_jiffies(500);
> +
> + dsi->irq_data &= ~CMD_DONE_INT_FLAG;

You should move this clearing of flag before mtk_dsi_start().

> +
> + ret = wait_event_interruptible_timeout(_dsi_irq_wait_queue,
> + dsi->irq_data & CMD_DONE_INT_FLAG, timeout);
> + if (ret == 0) {
> + dev_info(dsi->dev, "dsi wait engine cmd done fail\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
> +{
> + const char *tx_buf = msg->tx_buf;
> + u32 reg_val, i;
> + u16 wc16;
> + u8 config, data0, data1, type;
> +
> + if (MTK_DSI_HOST_IS_READ(type)) {

'type' is used before assigned.

> + config = 4;
> + data0 = tx_buf[0];
> +
> + if (msg->rx_len < 3)
> + type = MIPI_DSI_DCS_READ;
> + else
> + type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
> +
> + data1 = 0;
> + reg_val = (data1 << 24) | (data0 << 16) | (type << 8) | config;
> +
> + writel(reg_val, dsi->regs + DSI_CMDQ0);
> + mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, 1);

I think this part looks like 'else' part. The difference is type and
config. I think type should be msg->type and you can independently set
BIT(2) of config.

> + } else if (msg->tx_len > 2) {   /* send long packet */
> + config = 2;
> + type = msg->type;
> + wc16 = msg->tx_len;
> +
> + reg_val = (wc16 << 16) | (type << 8) | config;
> +
> + writel(reg_val, dsi->regs + DSI_CMDQ0);
> +
> + for (i = 0; i < msg->tx_len; i++)
> + writeb(tx_buf[i], dsi->regs + 

Re: [PATCH v5 06/10] drm/mediatek: add dsi interrupt control

2016-08-02 Thread CK Hu
Hi, YT:

On Thu, 2016-07-28 at 17:28 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi interrupt control
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |   92 
> 
>  1 file changed, 92 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a9cf5a1..553443a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -29,6 +30,17 @@
>  
>  #define DSI_START0x00
>  
> +#define DSI_INTEN0x08
> +
> +#define DSI_INTSTA   0x0c
> +#define LPRX_RD_RDY_INT_FLAG BIT(0)
> +#define CMD_DONE_INT_FLAGBIT(1)
> +#define TE_RDY_INT_FLAG  BIT(2)
> +#define VM_DONE_INT_FLAG BIT(3)
> +#define EXT_TE_RDY_INT_FLAG  BIT(4)
> +#define DSI_INT_ALL_BITS 0x7f
> +#define DSI_BUSY BIT(31)
> +
>  #define DSI_CON_CTRL 0x10
>  #define DSI_RESETBIT(0)
>  #define DSI_EN   BIT(1)
> @@ -71,6 +83,9 @@
>  
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RACK 0x84
> +#define RACK BIT(0)
> +
>  #define DSI_PHY_LCCON0x104
>  #define LC_HS_TX_EN  BIT(0)
>  #define LC_ULPM_EN   BIT(1)
> @@ -131,8 +146,13 @@ struct mtk_dsi {
>   struct videomode vm;
>   int refcount;
>   bool enabled;
> + int irq_data;
>  };
>  
> +static wait_queue_head_t _dsi_cmd_done_wait_queue;
> +static wait_queue_head_t _dsi_dcs_read_wait_queue;
> +static wait_queue_head_t _dsi_wait_vm_done_queue;

I think for difference irq status we can use only one wait queue. So
multiple client wait on the same wait queue, but each client has
different wake up condition.

> +
>  static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
>  {
>   return container_of(e, struct mtk_dsi, encoder);
> @@ -437,6 +457,55 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
>   writel(1, dsi->regs + DSI_START);
>  }
>  
> +static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
> +{
> + u32 inten = DSI_INT_ALL_BITS;
> +
> + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO)
> + inten &= ~(TE_RDY_INT_FLAG | EXT_TE_RDY_INT_FLAG);
> +
> + writel(inten, dsi->regs + DSI_INTEN);
> +}
> +
> +static void mtk_dsi_irq_wakeup(struct mtk_dsi *dsi, u32 irq_bit)
> +{
> + dsi->irq_data |= irq_bit;
> +}
> +
> +static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
> +{
> + struct mtk_dsi *dsi = dev_id;
> +
> + u32 status, tmp;
> +
> + status = readl(dsi->regs + DSI_INTSTA);
> +
> + if (status & LPRX_RD_RDY_INT_FLAG) {
> + do {
> + mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
> + tmp = readl(dsi->regs + DSI_INTSTA);
> + } while (tmp & DSI_BUSY);
> +
> + mtk_dsi_mask(dsi, DSI_INTSTA, LPRX_RD_RDY_INT_FLAG, 0);
> + mtk_dsi_irq_wakeup(dsi, LPRX_RD_RDY_INT_FLAG);
> + wake_up_interruptible(&_dsi_dcs_read_wait_queue);
> + }
> +
> + if (status & CMD_DONE_INT_FLAG) {
> + mtk_dsi_mask(dsi, DSI_INTSTA, CMD_DONE_INT_FLAG, 0);
> + mtk_dsi_irq_wakeup(dsi, CMD_DONE_INT_FLAG);
> + wake_up_interruptible(&_dsi_cmd_done_wait_queue);
> + }
> +
> + if (status & VM_DONE_INT_FLAG) {
> + mtk_dsi_mask(dsi, DSI_INTSTA, VM_DONE_INT_FLAG, 0);
> + mtk_dsi_irq_wakeup(dsi, VM_DONE_INT_FLAG);
> + wake_up_interruptible(&_dsi_wait_vm_done_queue);
> + }

I think these three part can be merged into one.
u32 deal_status = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG |
VM_DONE_INT_FLAG;
if (status & deal_status) {
mtk_dsi_mask(dsi, DSI_INTSTA, deal_status, 0);
mtk_dsi_irq_wakeup(dsi, status & deal_status);
wake_up_interruptible(&_dsi_irq_wait_queue);
}

Otherwise, why enable DSI_INT_ALL_BITS, but deal only
LPRX_RD_RDY_INT_FLAG, CMD_DONE_INT_FLAG, and VM_DONE_INT_FLAG?

> +
> + return IRQ_HANDLED;
> +}
> +
>  static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  {
>   if (WARN_ON(dsi->refcount == 0))
> @@ -485,6 +554,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>  
>   mtk_dsi_ps_control_vact(dsi);
>   mtk_dsi_config_vdo_timing(dsi);
> + mtk_dsi_set_interrupt_enable(dsi);
>  
>   mtk_dsi_set_mode(dsi);
>   mtk_dsi_clk_hs_mode(dsi, 1);
> @@ -804,6 +874,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   struct device *dev = >dev;
>   struct device_node *remote_node, *endpoint;
>   struct resource *regs;
> + int irq_num;
>   int comp_id;
>   int ret;
>  
> @@ -880,8 +951,29 @@ static int mtk_dsi_probe(struct 

Re: [PATCH v5 07/10] drm/mediatek: add dsi transfer function

2016-08-02 Thread CK Hu
Hi, YT:

On Thu, 2016-07-28 at 17:28 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  286 
> 
>  1 file changed, 286 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 553443a..1d36524 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -81,8 +82,16 @@
>  #define DSI_HBP_WC   0x54
>  #define DSI_HFP_WC   0x58
>  
> +#define DSI_CMDQ_SIZE0x60
> +#define CMDQ_SIZE0x3f
> +
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RX_DATA0 0x74
> +#define DSI_RX_DATA1 0x78
> +#define DSI_RX_DATA2 0x7c
> +#define DSI_RX_DATA3 0x80
> +
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> @@ -118,8 +127,25 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_CMDQ00x180
> +
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
> +#define MTK_DSI_HOST_IS_READ(type) \
> + ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> + (type == MIPI_DSI_DCS_READ))
> +
> +#define MTK_DSI_HOST_IS_WRITE(type) \
> + ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> + (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> + (type == MIPI_DSI_DCS_LONG_WRITE))
> +
>  struct phy;
>  
>  struct mtk_dsi {
> @@ -149,6 +175,17 @@ struct mtk_dsi {
>   int irq_data;
>  };
>  
> +struct dsi_rxtx_data {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq_regs {
> + struct dsi_rxtx_data data[128];
> +};
> +
>  static wait_queue_head_t _dsi_cmd_done_wait_queue;
>  static wait_queue_head_t _dsi_dcs_read_wait_queue;
>  static wait_queue_head_t _dsi_wait_vm_done_queue;
> @@ -813,9 +850,258 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return 0;
>  }
>  
> +static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
> +{
> + u32 temp = readl(reg);
> +
> + writel((temp & ~mask) | (data & mask), reg);
> +}
> +
> +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> +{
> + u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> +
> + while (timeout_ms--) {
> + if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> + break;
> +
> + usleep_range(2, 4);
> + }
> +
> + if (timeout_ms == 0) {
> + dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static void mtk_dsi_wait_for_cmd_done(struct mtk_dsi *dsi)
> +{
> + s32 ret = 0;
> + unsigned long timeout = msecs_to_jiffies(500);
> +
> + ret = wait_event_interruptible_timeout(_dsi_cmd_done_wait_queue,
> + dsi->irq_data & CMD_DONE_INT_FLAG, timeout);
> + if (ret == 0) {
> + dev_info(dsi->dev, "dsi wait engine cmd done fail\n");
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + return;
> + }
> +
> + dsi->irq_data &= ~CMD_DONE_INT_FLAG;

I think you should move this before trigger HW. Sometimes this interrupt
is coming and this flag is set but you do not wait this event and do not
clear it. Then when you want to wait, the flag is already set by long
time ago interrupt.

> +}
> +
> +static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
> +  const struct mipi_dsi_msg *msg)
> +{
> + u8 max_try_count = 5;
> + u32 recv_cnt, tmp_val;
> + struct dsi_rxtx_data read_data0, read_data1, read_data2, read_data3;
> + u8 config, type, data0, data1;
> + s32 ret;
> +
> + u8 *buffer = msg->rx_buf;
> + u8 buffer_size = msg->rx_len;
> +
> + if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
> + dev_info(dsi->dev, "dsi engine is not command mode\n");
> + return -1;
> + }
> +
> + if (!buffer) {
> + dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
> + return -1;
> + }
> +
> + do {
> + if (max_try_count == 0) {
> + dev_info(dsi->dev, "dsi engine read counter has 

Re: [GIT PULL] drm/mediatek: MT8173 gamma & dither support

2016-07-03 Thread CK Hu
Hi, Emil:

On Sun, 2016-07-03 at 23:43 +0100, Emil Velikov wrote:
> Hi Bibby,
> 
> On 27 June 2016 at 12:29, Bibby Hsieh <bibby.hs...@mediatek.com> wrote:
> > On Mon, 2016-06-27 at 12:20 +0200, Matthias Brugger wrote:
> >>
> >> On 06/24/2016 09:27 AM, Bibby Hsieh wrote:
> >> > Hi Dave,
> >> >
> >> > Please consider merging this tag, which contains the v2 MT8173 gamma & 
> >> > dither function patches I sent on 2016-06-17, rebased onto v4.7-rc1. 
> >> > There have been no further comments.
> >> >
> >> > Thanks
> >> > Bibby
> >> >
> >> > The following changes since commit 
> >> > 1a695a905c18548062509178b98bc91e67510864:
> >> >
> >> >   Linux 4.7-rc1 (2016-05-29 16:29:24 GMT)
> >> >
> >> > are available in the git repository at:
> >> >
> >> >   g...@github.com:BibbyHsieh/linux4.7-rc1.git
> >> >
> >> > for you to fetch changes up to dd0eb773bc125f5e6bca735d19c08500dc3730f9:
> >> >
> >> >   drm/mediatek: Add gamma correction
> >> >
> >> > -
> >>
> >> As far as I can see, your branch has 3 patches on top from Eddie. It
> >> seems to me as if you didn't send your patches to the mailinglist before?
> >> Anyway this branch does not fulfill the rules to get merged into the
> >> linux kernel.
> >>
> >> Why do you send a pull request? The normal process is to send the
> >> patches via email and if the maintainer wants you can send a pull
> >> request once the patches are ready to be merged.
> >>
> >> Regards,
> >> Matthias
> >>
> >
> > I sent v1 and v2 on 2016-06-14 and 06-17 respectively [0-8].
> > After I made some modifications according to Daniel Vetter's comments,
> > there had been no further comments and I sent the pull request as the
> > other sub-sys.
> >
> > I'm sorry for my mistake, I will re-arrange the tree for upstream.
> > Next time, I will check with maintainer by email first, and sent the
> > pull request.
> >
> It might be a bit hard to find out who's the maintainer considering
> MAINTAINERS has no entry for this driver.
> 
> Looking at how things are going Philipp Zabel will be the more likely
> person for the task, yet I would be nice if someone from the Mediatek
> squad is helping him out - CK Hu perhaps ?
> 
> Regards,
> Emil

I'm willing to be one of Mediatek DRM driver maintainer. I wish this
would make things easier.

Regards,
CK



Re: [PATCH v3] drm/mediatek: Support UYVY and YUYV format for overlay

2017-01-23 Thread CK Hu
Hi, Bibby:

On Tue, 2017-01-24 at 12:40 +0800, Bibby Hsieh wrote:
> MT8173 overlay can support UYVY and YUYV format,
> we add the format in DRM driver.
> 
> Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>
> Reviewed-by: Daniel Kurtz <djku...@chromium.org>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 7 +++
>  drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 ++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index c703102..53f2001 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -40,10 +40,13 @@
>  #define  OVL_RDMA_MEM_GMC0x40402020
>  
>  #define OVL_CON_BYTE_SWAPBIT(24)
> +#define OVL_CON_MTX_YUV_TO_RGB   (6 << 16)
>  #define OVL_CON_CLRFMT_RGB565(0 << 12)
>  #define OVL_CON_CLRFMT_RGB888(1 << 12)
>  #define OVL_CON_CLRFMT_RGBA  (2 << 12)
>  #define OVL_CON_CLRFMT_ARGB  (3 << 12)
> +#define OVL_CON_CLRFMT_UYVY  (4 << 12)
> +#define OVL_CON_CLRFMT_YUYV  (5 << 12)
>  #define  OVL_CON_AEN BIT(8)
>  #define  OVL_CON_ALPHA   0xff
>  
> @@ -162,6 +165,10 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
>   case DRM_FORMAT_XBGR:
>   case DRM_FORMAT_ABGR:
>   return OVL_CON_CLRFMT_RGBA | OVL_CON_BYTE_SWAP;
> + case DRM_FORMAT_UYVY:
> + return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
> + case DRM_FORMAT_YUYV:
> + return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB;
>   }
>  }
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index c461a23..8c02d1d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -28,6 +28,8 @@
>   DRM_FORMAT_XRGB,
>   DRM_FORMAT_ARGB,
>   DRM_FORMAT_RGB565,
> + DRM_FORMAT_UYVY,
> + DRM_FORMAT_YUYV,
>  };
>  
>  static void mtk_plane_reset(struct drm_plane *plane)




Re: [PATCH v12 11/12] drm/mediatek: update DSI sub driver flow for sending commands to panel

2017-01-23 Thread CK Hu
Hi, YT:

On Mon, 2017-01-23 at 19:05 +0800, YT Shen wrote:
> This patch update enable/disable flow of DSI module.
> Original flow works on there is a bridge chip: DSI -> bridge -> panel.
> In this case: DSI -> panel, the DSI sub driver flow should be updated.
> We need to initialize DSI first so that we can send commands to panel.
> 
> Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 266 
> ++---
>  1 file changed, 161 insertions(+), 105 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 85f22d2..aa3541e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -126,6 +126,10 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_VM_CMD_CON   0x130
> +#define VM_CMD_ENBIT(0)
> +#define TS_VFP_ENBIT(5)
> +
>  #define DSI_CMDQ00x180
>  #define CONFIG   (0xff << 0)
>  #define SHORT_PACKET 0
> @@ -239,85 +243,6 @@ static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
>  }
>  
> -static int mtk_dsi_poweron(struct mtk_dsi *dsi)
> -{
> - struct device *dev = dsi->dev;
> - int ret;
> - u64 pixel_clock, total_bits;
> - u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
> -
> - if (++dsi->refcount != 1)
> - return 0;
> -
> - switch (dsi->format) {
> - case MIPI_DSI_FMT_RGB565:
> - bit_per_pixel = 16;
> - break;
> - case MIPI_DSI_FMT_RGB666_PACKED:
> - bit_per_pixel = 18;
> - break;
> - case MIPI_DSI_FMT_RGB666:
> - case MIPI_DSI_FMT_RGB888:
> - default:
> - bit_per_pixel = 24;
> - break;
> - }
> -
> - /**
> -  * vm.pixelclock is in kHz, pixel_clock unit is Hz, so multiply by 1000
> -  * htotal_time = htotal * byte_per_pixel / num_lanes
> -  * overhead_time = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
> -  * mipi_ratio = (htotal_time + overhead_time) / htotal_time
> -  * data_rate = pixel_clock * bit_per_pixel * mipi_ratio / num_lanes;
> -  */
> - pixel_clock = dsi->vm.pixelclock * 1000;
> - htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
> - dsi->vm.hsync_len;
> - htotal_bits = htotal * bit_per_pixel;
> -
> - overhead_cycles = T_LPX + T_HS_PREP + T_HS_ZERO + T_HS_TRAIL +
> - T_HS_EXIT;
> - overhead_bits = overhead_cycles * dsi->lanes * 8;
> - total_bits = htotal_bits + overhead_bits;
> -
> - dsi->data_rate = DIV_ROUND_UP_ULL(pixel_clock * total_bits,
> -   htotal * dsi->lanes);
> -
> - ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
> - if (ret < 0) {
> - dev_err(dev, "Failed to set data rate: %d\n", ret);
> - goto err_refcount;
> - }
> -
> - phy_power_on(dsi->phy);
> -
> - ret = clk_prepare_enable(dsi->engine_clk);
> - if (ret < 0) {
> - dev_err(dev, "Failed to enable engine clock: %d\n", ret);
> - goto err_phy_power_off;
> - }
> -
> - ret = clk_prepare_enable(dsi->digital_clk);
> - if (ret < 0) {
> - dev_err(dev, "Failed to enable digital clock: %d\n", ret);
> - goto err_disable_engine_clk;
> - }
> -
> - mtk_dsi_enable(dsi);
> - mtk_dsi_reset_engine(dsi);
> - mtk_dsi_phy_timconfig(dsi);
> -
> - return 0;
> -
> -err_disable_engine_clk:
> - clk_disable_unprepare(dsi->engine_clk);
> -err_phy_power_off:
> - phy_power_off(dsi->phy);
> -err_refcount:
> - dsi->refcount--;
> - return ret;
> -}
> -
>  static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
> @@ -365,16 +290,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
>   u32 vid_mode = CMD_MODE;
>  
>   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
> - vid_mode = SYNC_PULSE_MODE;
> -
> - if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
> - !(dsi->mode_flags & MIPI_DS

Re: [PATCH] drm/mediatek: hdmi: Filter interlaced resolutions

2017-01-23 Thread CK Hu
Hi, Bibby:

On Tue, 2017-01-24 at 13:10 +0800, Bibby Hsieh wrote:
> Current Mediatek DRM driver does not support interlaced mode, and
> will hang if such resolution is used: Filter those to prevent
> kernel hangs, until the DRM driver is fixed properly.
> 
> Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
> b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 0e8c4d9..e33678d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1244,6 +1244,8 @@ static int mtk_hdmi_conn_mode_valid(struct 
> drm_connector *conn,
>   return MODE_BAD;
>   }
>  
> + if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> + return MODE_NO_INTERLACE;
>   if (mode->clock < 27000)
>   return MODE_CLOCK_LOW;
>   if (mode->clock > 297000)




Re: [PATCH v11 08/12] drm/mediatek: add dsi interrupt control

2017-01-17 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> From: shaoming chen <shaoming.c...@mediatek.com>
> 
> add dsi interrupt control
> 
> Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 92 
> ++
>  1 file changed, 92 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 6f4b3bb..474861a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -29,6 +30,16 @@
>  
>  #define DSI_START0x00
>  
> +#define DSI_INTEN0x08
> +
> +#define DSI_INTSTA   0x0c
> +#define LPRX_RD_RDY_INT_FLAG BIT(0)
> +#define CMD_DONE_INT_FLAGBIT(1)
> +#define TE_RDY_INT_FLAG  BIT(2)
> +#define VM_DONE_INT_FLAG BIT(3)
> +#define EXT_TE_RDY_INT_FLAG  BIT(4)
> +#define DSI_BUSY BIT(31)
> +
>  #define DSI_CON_CTRL 0x10
>  #define DSI_RESETBIT(0)
>  #define DSI_EN   BIT(1)
> @@ -71,6 +82,9 @@
>  
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RACK 0x84
> +#define RACK BIT(0)
> +
>  #define DSI_PHY_LCCON0x104
>  #define LC_HS_TX_EN  BIT(0)
>  #define LC_ULPM_EN   BIT(1)
> @@ -137,6 +151,8 @@ struct mtk_dsi {
>   struct videomode vm;
>   int refcount;
>   bool enabled;
> + u32 irq_data;
> + wait_queue_head_t irq_wait_queue;
>  };
>  
>  static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
> @@ -469,6 +485,64 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
>   writel(1, dsi->regs + DSI_START);
>  }
>  
> +static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
> +{
> + u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
> +
> + writel(inten, dsi->regs + DSI_INTEN);
> +}
> +
> +static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, u32 irq_bit)
> +{
> + dsi->irq_data |= irq_bit;
> +}
> +
> +static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 
> irq_bit)
> +{
> + dsi->irq_data &= ~irq_bit;
> +}
> +
> +static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 
> irq_flag,
> +  unsigned int timeout)
> +{
> + s32 ret = 0;
> + unsigned long jiffies = msecs_to_jiffies(timeout);
> +
> + ret = wait_event_interruptible_timeout(dsi->irq_wait_queue,
> +dsi->irq_data & irq_flag,
> +jiffies);
> + if (ret == 0) {
> + DRM_WARN("Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +
> + return ret;
> +}
> +
> +static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
> +{
> + struct mtk_dsi *dsi = dev_id;
> + u32 status, tmp;
> + u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
> +
> + status = readl(dsi->regs + DSI_INTSTA) & flag;
> +
> + if (status) {
> + do {
> + mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
> + tmp = readl(dsi->regs + DSI_INTSTA);
> + } while (tmp & DSI_BUSY);
> +
> + mtk_dsi_mask(dsi, DSI_INTSTA, status, 0);
> + mtk_dsi_irq_data_set(dsi, status);
> + wake_up_interruptible(>irq_wait_queue);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
>  static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  {
>   if (WARN_ON(dsi->refcount == 0))
> @@ -517,6 +591,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>  
>   mtk_dsi_ps_control_vact(dsi);
>   mtk_dsi_config_vdo_timing(dsi);
> + mtk_dsi_set_interrupt_enable(dsi);
>  
>   mtk_dsi_set_mode(dsi);
>   mtk_dsi_clk_hs_mode(dsi, 1);
> @@ -818,6 +893,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   struct device *dev = >dev;
>   struct device_node *remote_node, *endpoint;
>   struct resource *regs;
> + int irq_num;
>   int comp_id;
>   int ret;
>  
> @@ -894,6 +970,22 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>  

Re: [PATCH v11 09/12] drm/mediatek: add dsi transfer function

2017-01-17 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> From: shaoming chen <shaoming.c...@mediatek.com>
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 168 
> -
>  1 file changed, 166 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 474861a..b3c7fd8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -80,8 +81,16 @@
>  #define DSI_HBP_WC   0x54
>  #define DSI_HFP_WC   0x58
>  
> +#define DSI_CMDQ_SIZE0x60
> +#define CMDQ_SIZE0x3f
> +
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RX_DATA0 0x74
> +#define DSI_RX_DATA1 0x78
> +#define DSI_RX_DATA2 0x7c
> +#define DSI_RX_DATA3 0x80
> +
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> @@ -117,6 +126,15 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_CMDQ00x180
> +#define CONFIG   (0xff << 0)
> +#define SHORT_PACKET 0
> +#define LONG_PACKET  2
> +#define BTA  BIT(2)
> +#define DATA_ID  (0xff << 8)
> +#define DATA_0   (0xff << 16)
> +#define DATA_1   (0xff << 24)
> +
>  #define T_LPX5
>  #define T_HS_PREP6
>  #define T_HS_TRAIL   8
> @@ -125,6 +143,12 @@
>  
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
> +#define MTK_DSI_HOST_IS_READ(type) \
> + ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> + (type == MIPI_DSI_DCS_READ))
> +
>  struct phy;
>  
>  struct mtk_dsi {
> @@ -497,12 +521,12 @@ static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, 
> u32 irq_bit)
>   dsi->irq_data |= irq_bit;
>  }
>  
> -static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 
> irq_bit)
> +static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
>  {
>   dsi->irq_data &= ~irq_bit;
>  }
>  
> -static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 
> irq_flag,
> +static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
>unsigned int timeout)
>  {
>   s32 ret = 0;
> @@ -832,9 +856,149 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return 0;
>  }
>  
> +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> +{
> + u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> +
> + while (timeout_ms--) {
> + if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> + break;
> +
> + usleep_range(2, 4);
> + }
> +
> + if (timeout_ms == 0) {
> + DRM_WARN("polling dsi wait not busy timeout!\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data)
> +{
> + switch (type) {
> + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
> + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
> + return 1;
> + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
> + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
> + return 2;
> + case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
> + case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
> + return read_data[1] + read_data[2] * 16;
> + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
> + DRM_INFO("type is 0x02, try again\n");
> + break;
> + default:
> + DRM_INFO("type(0x%x) cannot be non-recognite\n", type);
> + break;
> + }
> +
> + return 0;
> +}
> +
> +static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
> +{
> + const char *tx_buf = msg->tx_buf;
> + u8 config, cmdq_s

Re: [PATCH v11 07/12] drm/mediatek: cleaning up and refine

2017-01-17 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> cleaning up unused define and refine function name and variable
> 
> Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 73 
> --
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c |  8 ++--
>  2 files changed, 39 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 2c42f90..6f4b3bb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -27,9 +27,6 @@
>  
>  #include "mtk_drm_ddp_comp.h"
>  
> -#define DSI_VIDEO_FIFO_DEPTH (1920 / 4)
> -#define DSI_HOST_FIFO_DEPTH  64
> -
>  #define DSI_START0x00
>  
>  #define DSI_CON_CTRL 0x10
> @@ -46,7 +43,7 @@
>  #define MIX_MODE BIT(17)
>  
>  #define DSI_TXRX_CTRL0x18
> -#define VC_NUM   (2 << 0)
> +#define VC_NUM   BIT(1)
>  #define LANE_NUM (0xf << 2)
>  #define DIS_EOT  BIT(6)
>  #define NULL_EN  BIT(7)
> @@ -164,7 +161,7 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, 
> u32 mask, u32 data)
>   writel((temp & ~mask) | (data & mask), dsi->regs + offset);
>  }
>  
> -static void dsi_phy_timconfig(struct mtk_dsi *dsi)
> +static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
>  {
>   u32 timcon0, timcon1, timcon2, timcon3;
>   u32 ui, cycle_time;
> @@ -196,7 +193,7 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
>  }
>  
> -static void mtk_dsi_reset(struct mtk_dsi *dsi)
> +static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
>   mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
> @@ -267,8 +264,8 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>   }
>  
>   mtk_dsi_enable(dsi);
> - mtk_dsi_reset(dsi);
> - dsi_phy_timconfig(dsi);
> + mtk_dsi_reset_engine(dsi);
> + mtk_dsi_phy_timconfig(dsi);
>  
>   return 0;
>  
> @@ -281,33 +278,33 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>   return ret;
>  }
>  
> -static void dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
> +static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
>  }
>  
> -static void dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
> +static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, LC_WAKEUP_EN);
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, 0);
>  }
>  
> -static void dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
> +static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
>   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
>  }
>  
> -static void dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
> +static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
>   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, LD0_WAKEUP_EN);
>   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, 0);
>  }
>  
> -static bool dsi_clk_hs_state(struct mtk_dsi *dsi)
> +static bool mtk_dsi_clk_hs_state(struct mtk_dsi *dsi)
>  {
>   u32 tmp_reg1;
>  
> @@ -315,15 +312,15 @@ static bool dsi_clk_hs_state(struct mtk_dsi *dsi)
>   return ((tmp_reg1 & LC_HS_TX_EN) == 1) ? true : false;
>  }
>  
> -static void dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
> +static void mtk_dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
>  {
> - if (enter && !dsi_clk_hs_state(dsi))
> + if (enter && !mtk_dsi_clk_hs_state(dsi))
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, LC_HS_TX_EN);
> - else if (!enter && dsi_clk_hs_state(dsi))
> + else if (!enter && mtk_dsi_clk_hs_state(dsi))
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
>  }
>  
> -static void dsi_set_mode(struct mtk_dsi *dsi)
> +static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
>  {
>   u32 vid_mode = CMD_MODE;
>  
> @@ -338,7 +335,7 @@ static void dsi_set_mode(

Re: [PATCH v11 10/12] drm/mediatek: add non-continuous clock mode and EOT packet control

2017-01-18 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> This patch will update dsi clock control method.
> 1. dsi non-continue clock mode will enhance antistatic effect for panel
> 2. EOT packet control will judge whether dsi send end of packet or not
> by customize
> 
> Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index b3c7fd8..85f22d2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -431,6 +431,9 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>   break;
>   }
>  
> + tmp_reg |= (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) << 6;
> + tmp_reg |= (dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET) >> 3;
> +
>   writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
>  }
>  




Re: [PATCH v11 12/12] drm/mediatek: add support for Mediatek SoC MT2701

2017-01-18 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  8 
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  6 ++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 17 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  7 +++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 29 
> +
>  drivers/gpu/drm/mediatek/mtk_dsi.c  |  1 +
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c  |  6 ++
>  7 files changed, 74 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 4552178..a14d7d6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -35,6 +35,7 @@
>  #define DISP_REG_OVL_PITCH(n)(0x0044 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_CTRL(n)(0x00c0 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
> +#define DISP_REG_OVL_ADDR_MT2701 0x0040
>  #define DISP_REG_OVL_ADDR_MT8173 0x0f40
>  #define DISP_REG_OVL_ADDR(ovl, n)((ovl)->data->addr + 0x20 * (n))
>  
> @@ -303,12 +304,19 @@ static int mtk_disp_ovl_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
> + .addr = DISP_REG_OVL_ADDR_MT2701,
> + .fmt_rgb565_is_0 = false,
> +};
> +
>  static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
>   .addr = DISP_REG_OVL_ADDR_MT8173,
>   .fmt_rgb565_is_0 = true,
>  };
>  
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-ovl",
> +   .data = _ovl_driver_data},
>   { .compatible = "mediatek,mt8173-disp-ovl",
> .data = _ovl_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index e5e5318..b68a513 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -236,11 +236,17 @@ static int mtk_disp_rdma_remove(struct platform_device 
> *pdev)
>   return 0;
>  }
>  
> +static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
> + .fifo_size = SZ_4K,
> +};
> +
>  static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
>   .fifo_size = SZ_8K,
>  };
>  
>  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
> + { .compatible = "mediatek,mt2701-disp-rdma",
> +   .data = _rdma_driver_data},
>   { .compatible = "mediatek,mt8173-disp-rdma",
> .data = _rdma_driver_data},
>   {},
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index a9b209c..8130f3d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -60,6 +60,13 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1   BIT(24)
>  #define MT8173_MUTEX_MOD_DISP_OD BIT(25)
>  
> +#define MT2701_MUTEX_MOD_DISP_OVLBIT(3)
> +#define MT2701_MUTEX_MOD_DISP_WDMA   BIT(6)
> +#define MT2701_MUTEX_MOD_DISP_COLOR  BIT(7)
> +#define MT2701_MUTEX_MOD_DISP_BLSBIT(9)
> +#define MT2701_MUTEX_MOD_DISP_RDMA0  BIT(10)
> +#define MT2701_MUTEX_MOD_DISP_RDMA1  BIT(12)
> +
>  #define MUTEX_SOF_SINGLE_MODE0
>  #define MUTEX_SOF_DSI0   1
>  #define MUTEX_SOF_DSI1   2
> @@ -92,6 +99,15 @@ struct mtk_ddp {
>   const unsigned int  *mutex_mod;
>  };
>  
> +static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> + [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
> + [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
> + [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
> + [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
> + [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
> + [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
> +};
> +
>  static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
>   [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
> @@ -390,6 +406,7 @@ static int mtk_ddp_remove(struct platform_device *pdev)
>  }
>  
>  static c

Re: [PATCH v11 11/12] drm/mediatek: update DSI sub driver flow for sending commands to panel

2017-01-18 Thread CK Hu
Hi, YT:

one comment inline.

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> This patch update enable/disable flow of DSI module.
> Original flow works on there is a bridge chip: DSI -> bridge -> panel.
> In this case: DSI -> panel, the DSI sub driver flow should be updated.
> We need to initialize DSI first so that we can send commands to panel.
> 
> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 89 
> +++---
>  1 file changed, 74 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 85f22d2..21392c4 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -126,6 +126,10 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_VM_CMD_CON   0x130
> +#define VM_CMD_ENBIT(0)
> +#define TS_VFP_ENBIT(5)
> +
>  #define DSI_CMDQ00x180
>  #define CONFIG   (0xff << 0)
>  #define SHORT_PACKET 0
> @@ -365,16 +369,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
>   u32 vid_mode = CMD_MODE;
>  
>   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
> - vid_mode = SYNC_PULSE_MODE;
> -
> - if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
> - !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
> + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
>   vid_mode = BURST_MODE;
> + else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> + vid_mode = SYNC_PULSE_MODE;
> + else
> + vid_mode = SYNC_EVENT_MODE;
>   }
>  
>   writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
>  }
>  
> +static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
> +{
> + mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
> + mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
> +}
> +
>  static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
>  {
>   struct videomode *vm = >vm;
> @@ -512,6 +523,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
>   writel(1, dsi->regs + DSI_START);
>  }
>  
> +static void mtk_dsi_stop(struct mtk_dsi *dsi)
> +{
> + writel(0, dsi->regs + DSI_START);
> +}
> +
> +static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
> +{
> + writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
> +}
> +
>  static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
>  {
>   u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
> @@ -570,6 +591,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
>   return IRQ_HANDLED;
>  }
>  
> +static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 
> t)
> +{
> + mtk_dsi_irq_data_clear(dsi, irq_flag);
> + mtk_dsi_set_cmd_mode(dsi);
> +
> + if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
> + DRM_ERROR("failed to switch cmd mode\n");
> + return -ETIME;
> + } else {
> + return 0;
> + }
> +}
> +
>  static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  {
>   if (WARN_ON(dsi->refcount == 0))
> @@ -578,6 +612,17 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>   if (--dsi->refcount != 0)
>   return;
>  
> + mtk_dsi_stop(dsi);
> + if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
> + if (dsi->panel) {
> + if (drm_panel_unprepare(dsi->panel)) {

Why drm_panel_unprepare() in mtk_dsi_poweroff() but drm_panel_prepare()
in mtk_output_dsi_enable()? This asymmetric design would easily cause
some bugs.

Regards,
CK

> + DRM_ERROR("failed to unprepare the panel\n");
> + return;
> + }
> + }
> + }
> +
> + mtk_dsi_reset_engine(dsi);
>   mtk_dsi_lane0_ulp_mode_enter(dsi);
>   mtk_dsi_clk_ulp_mode_enter(dsi);
>  
> @@ -596,13 +641,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>   if (dsi->enabled)
>   return;
>  
> - if (dsi->panel) {
> - if (drm_panel_prepare(dsi->panel)) {
> - DRM_ERROR("failed to setup the panel\n");
> - return;
> - }
> - }
> -
>   ret = mtk_dsi_poweron(dsi);
>   if (ret < 0) {
>   DRM_ERROR("failed to power on dsi\n");
> @@ -610,22 +648,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>   }
>  
>   mtk_dsi_rxtx_control(dsi);
> + mtk_dsi_ps_control_vact(dsi);
> + mtk_dsi_set_vm_cmd(dsi);
> + mtk_dsi_config_vdo_timing(dsi);
> + mtk_dsi_set_interrupt_enable(dsi);
>  
>   mtk_dsi_clk_ulp_mode_leave(dsi);
>   

Re: [PATCH v11 05/12] drm/mediatek: add BLS component

2017-01-16 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> Add BLS component for PWM + GAMMA function
> 
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 5 -
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 3ff788c..f6e853a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -255,6 +255,7 @@ static void mtk_gamma_set(struct mtk_ddp_comp *comp,
>   [MTK_DISP_PWM] = "pwm",
>   [MTK_DISP_MUTEX] = "mutex",
>   [MTK_DISP_OD] = "od",
> + [MTK_DISP_BLS] = "bls",
>  };
>  
>  struct mtk_ddp_comp_match {
> @@ -265,6 +266,7 @@ struct mtk_ddp_comp_match {
>  
>  static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] 
> = {
>   [DDP_COMPONENT_AAL] = { MTK_DISP_AAL,   0, _aal },
> + [DDP_COMPONENT_BLS] = { MTK_DISP_BLS,   0, NULL },
>   [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR, 0, _color },
>   [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR, 1, _color },
>   [DDP_COMPONENT_DPI0]= { MTK_DPI,0, NULL },
> @@ -336,7 +338,8 @@ int mtk_ddp_comp_init(struct device *dev, struct 
> device_node *node,
>   comp->id = comp_id;
>   comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
>  
> - if (comp_id == DDP_COMPONENT_DPI0 ||
> + if (comp_id == DDP_COMPONENT_BLS ||
> + comp_id == DDP_COMPONENT_DPI0 ||
>   comp_id == DDP_COMPONENT_DSI0 ||
>   comp_id == DDP_COMPONENT_PWM0) {
>   comp->regs = NULL;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 22a33ee..0828cf8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -36,11 +36,13 @@ enum mtk_ddp_comp_type {
>   MTK_DISP_PWM,
>   MTK_DISP_MUTEX,
>   MTK_DISP_OD,
> + MTK_DISP_BLS,
>   MTK_DDP_COMP_TYPE_MAX,
>  };
>  
>  enum mtk_ddp_comp_id {
>   DDP_COMPONENT_AAL,
> + DDP_COMPONENT_BLS,
>   DDP_COMPONENT_COLOR0,
>   DDP_COMPONENT_COLOR1,
>   DDP_COMPONENT_DPI0,




Re: [PATCH v11 06/12] drm/mediatek: update display module connections

2017-01-16 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> update connections for OVL, RDMA, BLS, DSI
> 
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 25 +
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> index b77d456..a9b209c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> @@ -32,6 +32,10 @@
>  #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN   0x0c8
>  #define DISP_REG_CONFIG_MMSYS_CG_CON00x100
>  
> +#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030
> +#define DISP_REG_CONFIG_OUT_SEL  0x04c
> +#define DISP_REG_CONFIG_DSI_SEL  0x050
> +
>  #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
>  #define DISP_REG_MUTEX(n)(0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)(0x28 + 0x20 * (n))
> @@ -71,6 +75,10 @@
>  #define DPI0_SEL_IN_RDMA10x1
>  #define COLOR1_SEL_IN_OVL1   0x1
>  
> +#define OVL_MOUT_EN_RDMA 0x1
> +#define BLS_TO_DSI_RDMA1_TO_DPI1 0x8
> +#define DSI_SEL_IN_BLS   0x0
> +
>  struct mtk_disp_mutex {
>   int id;
>   bool claimed;
> @@ -111,6 +119,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id 
> cur,
>   if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
>   *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
>   value = OVL0_MOUT_EN_COLOR0;
> + } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
> + *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
> + value = OVL_MOUT_EN_RDMA;
>   } else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) {
>   *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
>   value = OD_MOUT_EN_RDMA0;
> @@ -148,6 +159,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id 
> cur,
>   } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
>   *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
>   value = COLOR1_SEL_IN_OVL1;
> + } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
> + *addr = DISP_REG_CONFIG_DSI_SEL;
> + value = DSI_SEL_IN_BLS;
>   } else {
>   value = 0;
>   }
> @@ -155,6 +169,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id 
> cur,
>   return value;
>  }
>  
> +static void mtk_ddp_sout_sel(void __iomem *config_regs,
> +  enum mtk_ddp_comp_id cur,
> +  enum mtk_ddp_comp_id next)
> +{
> + if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0)
> + writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
> +config_regs + DISP_REG_CONFIG_OUT_SEL);
> +}
> +
>  void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
> enum mtk_ddp_comp_id cur,
> enum mtk_ddp_comp_id next)
> @@ -167,6 +190,8 @@ void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
>   writel_relaxed(reg, config_regs + addr);
>   }
>  
> + mtk_ddp_sout_sel(config_regs, cur, next);
> +
>   value = mtk_ddp_sel_in(cur, next, );
>   if (value) {
>   reg = readl_relaxed(config_regs + addr) | value;




Re: [PATCH v11 04/12] drm/mediatek: add shadow register support

2017-01-16 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> We need to acquire mutex before using the resources,
> and need to release it after finished.
> So we don't need to write registers in the blanking period.
> 
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 75 
> -
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 25 +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |  2 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  1 +
>  4 files changed, 74 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 01a21dd..b9b82e5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -329,6 +329,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
> *mtk_crtc)
>   pm_runtime_put(drm->dev);
>  }
>  
> +static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
> +{
> + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> + struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
> + unsigned int i;
> +
> + /*
> +  * TODO: instead of updating the registers here, we should prepare
> +  * working registers in atomic_commit and let the hardware command
> +  * queue update module registers on vblank.
> +  */
> + if (state->pending_config) {
> + mtk_ddp_comp_config(ovl, state->pending_width,
> + state->pending_height,
> + state->pending_vrefresh, 0);
> +
> + state->pending_config = false;
> + }
> +
> + if (mtk_crtc->pending_planes) {
> + for (i = 0; i < OVL_LAYER_NR; i++) {
> + struct drm_plane *plane = _crtc->planes[i];
> + struct mtk_plane_state *plane_state;
> +
> + plane_state = to_mtk_plane_state(plane->state);
> +
> + if (plane_state->pending.config) {
> + mtk_ddp_comp_layer_config(ovl, i, plane_state);
> + plane_state->pending.config = false;
> + }
> + }
> + mtk_crtc->pending_planes = false;
> + }
> +}
> +
>  static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> @@ -405,6 +441,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
> struct drm_crtc_state *old_crtc_state)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_drm_private *priv = crtc->dev->dev_private;
>   unsigned int pending_planes = 0;
>   int i;
>  
> @@ -426,6 +463,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
>   if (crtc->state->color_mgmt_changed)
>   for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
>   mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
> +
> + if (priv->data->shadow_register) {
> + mtk_disp_mutex_acquire(mtk_crtc->mutex);
> + mtk_crtc_ddp_config(crtc);
> + mtk_disp_mutex_release(mtk_crtc->mutex);
> + }
>  }
>  
>  static const struct drm_crtc_funcs mtk_crtc_funcs = {
> @@ -471,36 +514,10 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
>  void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
>  {
>   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> - struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
> - unsigned int i;
> + struct mtk_drm_private *priv = crtc->dev->dev_private;
>  
> - /*
> -  * TODO: instead of updating the registers here, we should prepare
> -  * working registers in atomic_commit and let the hardware command
> -  * queue update module registers on vblank.
> -  */
> - if (state->pending_config) {
> - mtk_ddp_comp_config(ovl, state->pending_width,
> - state->pending_height,
> - state->pending_vrefresh, 0);
> -
> - state->pending_config = false;
> - }
> -
> - if (mtk_crtc->pending_planes) {
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = _crtc->planes[i];
> - struct mtk_pl

Re: [PATCH v11 03/12] drm/mediatek: add *driver_data for different hardware settings

2017-01-16 Thread CK Hu
Hi, YT:

On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> There are some hardware settings changed, between MT8173 & MT2701:
> DISP_OVL address offset changed, color format definition changed.
> DISP_RDMA fifo size changed.
> DISP_COLOR offset changed.
> MIPI_TX pll setting changed.
> And add prefix for mtk_ddp_main & mtk_ddp_ext & mutex_mod.
> 
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by: CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 41 -
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 18 +++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 71 
> +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 +++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 25 +++---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  8 
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c  | 24 +-
>  7 files changed, 181 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index ce2759f..4552178 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -35,18 +35,27 @@
>  #define DISP_REG_OVL_PITCH(n)(0x0044 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_CTRL(n)(0x00c0 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
> -#define DISP_REG_OVL_ADDR(n) (0x0f40 + 0x20 * (n))
> +#define DISP_REG_OVL_ADDR_MT8173 0x0f40
> +#define DISP_REG_OVL_ADDR(ovl, n)((ovl)->data->addr + 0x20 * (n))
>  
>  #define  OVL_RDMA_MEM_GMC0x40402020
>  
>  #define OVL_CON_BYTE_SWAPBIT(24)
> -#define OVL_CON_CLRFMT_RGB565(0 << 12)
> -#define OVL_CON_CLRFMT_RGB888(1 << 12)
> +#define OVL_CON_CLRFMT_RGB   (1 << 12)
>  #define OVL_CON_CLRFMT_RGBA  (2 << 12)
>  #define OVL_CON_CLRFMT_ARGB  (3 << 12)
> +#define OVL_CON_CLRFMT_RGB565(ovl)   ((ovl)->data->fmt_rgb565_is_0 ? \
> + 0 : OVL_CON_CLRFMT_RGB)
> +#define OVL_CON_CLRFMT_RGB888(ovl)   ((ovl)->data->fmt_rgb565_is_0 ? \
> + OVL_CON_CLRFMT_RGB : 0)
>  #define  OVL_CON_AEN BIT(8)
>  #define  OVL_CON_ALPHA   0xff
>  
> +struct mtk_disp_ovl_data {
> + unsigned int addr;
> + bool fmt_rgb565_is_0;
> +};
> +
>  /**
>   * struct mtk_disp_ovl - DISP_OVL driver structure
>   * @ddp_comp - structure containing type enum and hardware resources
> @@ -55,6 +64,7 @@
>  struct mtk_disp_ovl {
>   struct mtk_ddp_comp ddp_comp;
>   struct drm_crtc *crtc;
> + const struct mtk_disp_ovl_data  *data;
>  };
>  
>  static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
> @@ -141,18 +151,18 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp 
> *comp, unsigned int idx)
>   writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
>  }
>  
> -static unsigned int ovl_fmt_convert(unsigned int fmt)
> +static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int 
> fmt)
>  {
>   switch (fmt) {
>   default:
>   case DRM_FORMAT_RGB565:
> - return OVL_CON_CLRFMT_RGB565;
> + return OVL_CON_CLRFMT_RGB565(ovl);
>   case DRM_FORMAT_BGR565:
> - return OVL_CON_CLRFMT_RGB565 | OVL_CON_BYTE_SWAP;
> + return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
>   case DRM_FORMAT_RGB888:
> - return OVL_CON_CLRFMT_RGB888;
> + return OVL_CON_CLRFMT_RGB888(ovl);
>   case DRM_FORMAT_BGR888:
> - return OVL_CON_CLRFMT_RGB888 | OVL_CON_BYTE_SWAP;
> + return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
>   case DRM_FORMAT_RGBX:
>   case DRM_FORMAT_RGBA:
>   return OVL_CON_CLRFMT_ARGB;
> @@ -171,6 +181,7 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
>  static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
>struct mtk_plane_state *state)
>  {
> + struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
>   struct mtk_plane_pending_state *pending = >pending;
>   unsigned int addr = pending->addr;
>   unsigned int pitch = pending->pitch & 0x;
> @@ -182,7 +193,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp 
> *comp, unsigned int idx,
>   if (!pending->enable)
>   mtk_ovl_layer_off(comp, idx);
>  
> - con = ovl_fmt_convert(f

Re: [PATCH v7 2/9] drm/mediatek: add *driver_data for different hardware settings

2016-09-06 Thread CK Hu
Hi, YT:

On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> There are some hardware settings changed, between MT8173 & MT2701:
> DISP_OVL address offset changed, color format definition changed.
> DISP_RDMA fifo size changed.
> DISP_COLOR offset changed.
> MIPI_TX pll setting changed.
> And add prefix for mtk_ddp_main & mtk_ddp_ext & mutex_mod.
> 
> Signed-off-by: YT Shen 
> ---

[snip...]

>  
> @@ -185,7 +183,8 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp 
> *comp, unsigned int idx,
>   writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
>   writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
>   writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx));
> - writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(idx));

DISP_REG_OVL_ADDR() is useless, so remove it.

> + writel_relaxed(addr, comp->regs + comp->data->ovl.addr_offset
> + + idx * 0x20);
>  
>   if (pending->enable)
>   mtk_ovl_layer_on(comp, idx);


Regards,
CK



Re: [PATCH v7 4/9] drm/mediatek: update display module connections

2016-09-06 Thread CK Hu
Hi, YT:

On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> update connections for OVL, RDMA, BLS, DSI
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 25 +
>  1 file changed, 25 insertions(+)
> 

[snip...]

> @@ -111,6 +119,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id 
> cur,
>   if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
>   *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
>   value = OVL0_MOUT_EN_COLOR0;
> + } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
> + *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
> + value = OVL_MOUT_EN_RDMA;
>   } else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) {
>   *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
>   value = OD_MOUT_EN_RDMA0;
> @@ -148,6 +159,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id 
> cur,
>   } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
>   *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
>   value = COLOR1_SEL_IN_OVL1;
> + } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {

DDP_COMPONENT_BLS is a new symbol which is defined in 9th patch of this
series. I think the definition of DDP_COMPONENT_BLS should be in front
of this patch.

> + *addr = DISP_REG_CONFIG_DSI_SEL;
> + value = DSI_SEL_IN_BLS;
>   } else {
>   value = 0;
>   }
> @@ -155,6 +169,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id 
> cur,
>   return value;
>  }
>  

Regards,
CK




Re: [PATCH v7 7/9] drm/mediatek: add dsi transfer function

2016-09-06 Thread CK Hu
Hi, YT:

On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 188 
> +
>  1 file changed, 188 insertions(+)
> 

[snip...]

>  
> +static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
> +{
> + dsi->irq_data &= ~irq_bit;
> +}
> +

[snip...]

> +
> +static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
> +  unsigned int timeout)
> +{
> + s32 ret = 0;
> + unsigned long jiffies = msecs_to_jiffies(timeout);
> +
> + ret = wait_event_interruptible_timeout(_dsi_irq_wait_queue,
> +dsi->irq_data & irq_flag,
> +jiffies);
> + if (ret == 0) {
> + dev_info(dsi->dev, "Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +
> + return ret;
> +}

I think mtk_dsi_irq_data_clear() and mtk_dsi_wait_for_irq_done() should
be moved to the 6th patch [1] of this series because these two functions
deal the irq control.


[1] https://patchwork.kernel.org/patch/9310819/


Regards,
CK



Re: [PATCH v7 6/9] drm/mediatek: add dsi interrupt control

2016-09-06 Thread CK Hu
Hi, YT:

On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi interrupt control
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 76 
> ++
>  1 file changed, 76 insertions(+)
> 

[snip...]

>  
> +static wait_queue_head_t _dsi_irq_wait_queue;

I think it's better to move this global variable into platform driver
data. Maybe one day you have two dsi device and one global variable is
not enough.

> +

[snip...]

> +
> +static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
> +{
> + struct mtk_dsi *dsi = dev_id;
> + u32 status, tmp;
> + u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
> +
> + status = readl(dsi->regs + DSI_INTSTA);

If you define as

status = readl(dsi->regs + DSI_INTSTA) & flag;

You can remove 'flag' in below statements and reduce code size.

> +
> + if (status & flag) {
> + do {
> + mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
> + tmp = readl(dsi->regs + DSI_INTSTA);
> + } while (tmp & DSI_BUSY);
> +
> + mtk_dsi_mask(dsi, DSI_INTSTA, status & flag, 0);
> + mtk_dsi_irq_data_set(dsi, status & flag);
> + wake_up_interruptible(&_dsi_irq_wait_queue);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +

[snip...]

>  
> @@ -869,8 +926,27 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   return ret;
>   }
>  
> + irq_num = platform_get_irq(pdev, 0);
> + if (irq_num < 0) {
> + dev_err(>dev, "failed to request dsi irq resource\n");
> + return -EPROBE_DEFER;
> + }
> +
> + irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
> + ret = devm_request_irq(>dev, irq_num, mtk_dsi_irq,
> +IRQF_TRIGGER_LOW, dev_name(>dev), dsi);
> + if (ret) {
> + dev_err(>dev, "failed to request mediatek dsi irq\n");
> + return -EPROBE_DEFER;
> + }
> +
> + dsi->irq_data = 0;

You use devm_kzalloc() to allocate 'dsi', so this statement is
redundant.

> + dev_info(dev, "dsi irq num is 0x%x\n", irq_num);
> +
>   platform_set_drvdata(pdev, dsi);
>  
> + init_waitqueue_head(&_dsi_irq_wait_queue);
> +
>   return component_add(>dev, _dsi_component_ops);
>  }


Regards,
CK 




Re: [PATCH v7 8/9] drm/mediatek: update DSI sub driver flow

2016-09-06 Thread CK Hu
Hi, YT:

On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> This patch update enable/disable flow of DSI module and MIPI TX module
> 
> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---

I think the description is too simple. Please briefly describe WHY of
this patch. The original enable/disable flow is workable, so why do you
need this patch? Without this patch, what problem would happen?

Regards,
CK




Re: [PATCH v4 3/3] drm/mediatek: fix the wrong pixel clock when resolution is 4K

2016-09-11 Thread CK Hu
Hi, Bibby:

Sorry for the late reply.

On Wed, 2016-08-17 at 14:58 +0800, Bibby Hsieh wrote:
> From: Junzhi Zhao 
> 
> Pixel clock should be 297MHz when resolution is 4K.
> 

>From the code you modified, I think title should be: "Enlarge pll_rate
range from (, ) to (, )"

In description, you can explain the pll_rate for 4K and this enlargement
could support more resolution include 4K (Not only 4K).

> Signed-off-by: Junzhi Zhao 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c |9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 0186e50..90fb831 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -432,11 +432,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   unsigned long pll_rate;
>   unsigned int factor;
>  
> + /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
>   pix_rate = 1000UL * mode->clock;
> - if (mode->clock <= 74000)
> + if (mode->clock <= 27000)
> + factor = 16 * 3;
> + else if (mode->clock <= 84000)
>   factor = 8 * 3;
> - else
> + else if (mode->clock <= 167000)
>   factor = 4 * 3;
> + else
> + factor = 2 * 3;
>   pll_rate = pix_rate * factor;
>  
>   dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",

Regards,
CK



Re: [PATCH v8 8/9] drm/mediatek: update DSI sub driver flow

2016-09-13 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 20:01 +0800, YT Shen wrote:
> This patch update enable/disable flow of DSI module and MIPI TX module.
> Original flow works on there is a bridge chip: DSI -> bridge -> panel.
> In this case: DSI -> panel, the DSI sub driver flow should be updated.
> We need to initialize DSI first so that we can send commands to panel.
> 
> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---
>  

[snip...]

>  
> +static void mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi)
> +{
> + s32 ret = 0;
> + unsigned long timeout = msecs_to_jiffies(500);
> +
> + mtk_dsi_irq_data_clear(dsi, VM_DONE_INT_FLAG);
> + mtk_dsi_set_cmd_mode(dsi);
> +
> + ret = wait_event_interruptible_timeout(dsi->irq_wait_queue,
> +dsi->irq_data & VM_DONE_INT_FLAG,
> +timeout);
> + if (ret == 0) {
> + dev_info(dsi->dev, "dsi wait engine idle timeout\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }

I think you should replace this event-waiting with
mtk_dsi_wait_for_irq_done(). And this is a reason for moving
mtk_dsi_wait_for_irq_done() to the patch of irq control.

> +}
> +
>  static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  {
>   if (WARN_ON(dsi->refcount == 0))
> @@ -528,6 +574,17 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>   if (--dsi->refcount != 0)
>   return;
>  
> + mtk_dsi_switch_to_cmd_mode(dsi);
> +
> + if (dsi->panel) {
> + if (drm_panel_unprepare(dsi->panel)) {
> + DRM_ERROR("failed to unprepare the panel\n");
> + return;
> + }
> + }

I think drm_panel_unprepare should be placed after dsi is disabled. So
move this part after calling mtk_dsi_poweroff() in
mtk_output_dsi_disable().

> +
> + mtk_dsi_reset_engine(dsi);
> +
>   mtk_dsi_lane0_ulp_mode_enter(dsi);
>   mtk_dsi_clk_ulp_mode_enter(dsi);
>  
> @@ -546,29 +603,37 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>   if (dsi->enabled)
>   return;
>  
> - if (dsi->panel) {
> - if (drm_panel_prepare(dsi->panel)) {
> - DRM_ERROR("failed to setup the panel\n");
> - return;
> - }
> - }
> -
>   ret = mtk_dsi_poweron(dsi);
>   if (ret < 0) {
>   DRM_ERROR("failed to power on dsi\n");
>   return;
>   }
>  
> + usleep_range(2, 21000);
> +
>   mtk_dsi_rxtx_control(dsi);
> + mtk_dsi_phy_timconfig(dsi);
> + mtk_dsi_ps_control_vact(dsi);
> + mtk_dsi_set_vm_cmd(dsi);
> + mtk_dsi_config_vdo_timing(dsi);
> + mtk_dsi_set_interrupt_enable(dsi);
>  
> + mtk_dsi_enable(dsi);
>   mtk_dsi_clk_ulp_mode_leave(dsi);
>   mtk_dsi_lane0_ulp_mode_leave(dsi);
>   mtk_dsi_clk_hs_mode(dsi, 0);
> - mtk_dsi_set_mode(dsi);
>  
> - mtk_dsi_ps_control_vact(dsi);
> - mtk_dsi_config_vdo_timing(dsi);
> - mtk_dsi_set_interrupt_enable(dsi);
> + if (dsi->panel) {
> + if (drm_panel_prepare(dsi->panel)) {
> + DRM_ERROR("failed to prepare the panel\n");
> + return;
> + }
> +
> + if (drm_panel_enable(dsi->panel)) {
> + DRM_ERROR("failed to enable the panel\n");
> + return;
> + }
> + }

I think drm_panel_prepare() should be called before DSI is enabled and
drm_panel_enable() should be called after DSI is enabled. But you may
encounter the problem that panel need transfer data when prepare and you
can refer to [1].

[1]
http://lxr.free-electrons.com/source/drivers/gpu/drm/exynos/exynos_drm_dsi.c#L1431

>  
>   mtk_dsi_set_mode(dsi);
>   mtk_dsi_clk_hs_mode(dsi, 1);
> @@ -590,6 +655,7 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
>   }
>   }
>  
> + mtk_dsi_stop(dsi);
>   mtk_dsi_poweroff(dsi);
>  
>   dsi->enabled = false;
> diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c 
> b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> index 108d31a..34e95c6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> @@ -177,7 +177,9 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
>  
>   dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
>  
> - if (mipi_tx->data_rate >= 5) {
> + if (mipi_tx->data_rate > 125000) {
> + return -EINVAL;
> + } else if (mipi_tx->data_rate >= 5) {

What is the relationship of this part and "DSI driver flow"? Would this
be an independent patch?

>   txdiv = 1;
>   txdiv0 = 0;
>   txdiv1 = 0;
> @@ -201,6 +203,10 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
>   return -EINVAL;
>   }
>  
> + 

Re: [PATCH v7 7/9] drm/mediatek: add dsi transfer function

2016-09-14 Thread CK Hu
Hi, YT:

On Wed, 2016-09-14 at 14:19 +0800, YT Shen wrote:
> Hi CK,
> 
> On Tue, 2016-09-13 at 17:25 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Mon, 2016-09-12 at 18:16 +0800, YT Shen wrote:
> > > Hi CK,
> > > 
> > > On Wed, 2016-09-07 at 10:33 +0800, CK Hu wrote:
> > > > Hi, YT:
> > > > 
> > > > On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> > > > > From: shaoming chen <shaoming.c...@mediatek.com>
> > > > > 
> > > > > add dsi read/write commands for transfer function
> > > > > 
> > > > > Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> > > > > ---
> > > > >  drivers/gpu/drm/mediatek/mtk_dsi.c | 188 
> > > > > +
> > > > >  1 file changed, 188 insertions(+)
> > > > > 
> > > > 
> > > > [snip...]
> > > > 
> > > > >  
> > > > > +static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
> > > > > +{
> > > > > + dsi->irq_data &= ~irq_bit;
> > > > > +}
> > > > > +
> > > > 
> > > > [snip...]
> > > > 
> > > > > +
> > > > > +static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 
> > > > > irq_flag,
> > > > > +  unsigned int timeout)
> > > > > +{
> > > > > + s32 ret = 0;
> > > > > + unsigned long jiffies = msecs_to_jiffies(timeout);
> > > > > +
> > > > > + ret = wait_event_interruptible_timeout(_dsi_irq_wait_queue,
> > > > > +dsi->irq_data & irq_flag,
> > > > > +jiffies);
> > > > > + if (ret == 0) {
> > > > > + dev_info(dsi->dev, "Wait DSI IRQ(0x%08x) Timeout\n", 
> > > > > irq_flag);
> > > > > +
> > > > > + mtk_dsi_enable(dsi);
> > > > > + mtk_dsi_reset_engine(dsi);
> > > > > + }
> > > > > +
> > > > > + return ret;
> > > > > +}
> > > > 
> > > > I think mtk_dsi_irq_data_clear() and mtk_dsi_wait_for_irq_done() should
> > > > be moved to the 6th patch [1] of this series because these two functions
> > > > deal the irq control.
> > > We will move mtk_dsi_irq_data_clear() to patch "drm/mediatek: add dsi
> > > interrupt control" and put mtk_dsi_wait_for_irq_done() here, because it
> > > is used in the transfer function.
> > 
> > mtk_dsi_irq_data_clear() is also only used in transfer function now. I
> > think both function could be used for other application rather than
> > transfer function, so these two function are general function for irq
> > control.
> We will rollback the changes here.  Move mtk_dsi_irq_data_clear() to
> original place.
> 
> Add new functions could be used in the future will have problems.
> warning: 'mtk_dsi_wait_for_irq_done' defined but not used
> [-Wunused-function]
>  static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
> warning: 'mtk_dsi_irq_data_clear' defined but not used
> [-Wunused-function]
>  static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)

Please refer to [1], '__maybe_unused' can fix your problem.

[1]
http://lxr.free-electrons.com/source/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c#L76

Regards,
CK

> 
> > Regards,
> > CK
> > 
> > > 
> > > Regards,
> > > yt.shen
> > > > 
> > > > 
> > > > [1] https://patchwork.kernel.org/patch/9310819/
> > > > 
> > > > 
> > > > Regards,
> > > > CK
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 




Re: [PATCH v7 7/9] drm/mediatek: add dsi transfer function

2016-09-14 Thread CK Hu
Hi, YT:

On Wed, 2016-09-14 at 15:22 +0800, YT Shen wrote:
> Hi CK,
> 
> On Wed, 2016-09-14 at 14:39 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Wed, 2016-09-14 at 14:19 +0800, YT Shen wrote:
> > > Hi CK,
> > > 
> > > On Tue, 2016-09-13 at 17:25 +0800, CK Hu wrote:
> > > > Hi, YT:
> > > > 
> > > > On Mon, 2016-09-12 at 18:16 +0800, YT Shen wrote:
> > > > > Hi CK,
> > > > > 
> > > > > On Wed, 2016-09-07 at 10:33 +0800, CK Hu wrote:
> > > > > > Hi, YT:
> > > > > > 
> > > > > > On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> > > > > > > From: shaoming chen <shaoming.c...@mediatek.com>
> > > > > > > 
> > > > > > > add dsi read/write commands for transfer function
> > > > > > > 
> > > > > > > Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/mediatek/mtk_dsi.c | 188 
> > > > > > > +
> > > > > > >  1 file changed, 188 insertions(+)
> > > > > > > 
> > > > > > 
> > > > > > [snip...]
> > > > > > 
> > > > > > >  
> > > > > > > +static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 
> > > > > > > irq_bit)
> > > > > > > +{
> > > > > > > + dsi->irq_data &= ~irq_bit;
> > > > > > > +}
> > > > > > > +
> > > > > > 
> > > > > > [snip...]
> > > > > > 
> > > > > > > +
> > > > > > > +static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 
> > > > > > > irq_flag,
> > > > > > > +  unsigned int timeout)
> > > > > > > +{
> > > > > > > + s32 ret = 0;
> > > > > > > + unsigned long jiffies = msecs_to_jiffies(timeout);
> > > > > > > +
> > > > > > > + ret = wait_event_interruptible_timeout(_dsi_irq_wait_queue,
> > > > > > > +dsi->irq_data & irq_flag,
> > > > > > > +jiffies);
> > > > > > > + if (ret == 0) {
> > > > > > > + dev_info(dsi->dev, "Wait DSI IRQ(0x%08x) Timeout\n", 
> > > > > > > irq_flag);
> > > > > > > +
> > > > > > > + mtk_dsi_enable(dsi);
> > > > > > > + mtk_dsi_reset_engine(dsi);
> > > > > > > + }
> > > > > > > +
> > > > > > > + return ret;
> > > > > > > +}
> > > > > > 
> > > > > > I think mtk_dsi_irq_data_clear() and mtk_dsi_wait_for_irq_done() 
> > > > > > should
> > > > > > be moved to the 6th patch [1] of this series because these two 
> > > > > > functions
> > > > > > deal the irq control.
> > > > > We will move mtk_dsi_irq_data_clear() to patch "drm/mediatek: add dsi
> > > > > interrupt control" and put mtk_dsi_wait_for_irq_done() here, because 
> > > > > it
> > > > > is used in the transfer function.
> > > > 
> > > > mtk_dsi_irq_data_clear() is also only used in transfer function now. I
> > > > think both function could be used for other application rather than
> > > > transfer function, so these two function are general function for irq
> > > > control.
> > > We will rollback the changes here.  Move mtk_dsi_irq_data_clear() to
> > > original place.
> > > 
> > > Add new functions could be used in the future will have problems.
> > > warning: 'mtk_dsi_wait_for_irq_done' defined but not used
> > > [-Wunused-function]
> > >  static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
> > > warning: 'mtk_dsi_irq_data_clear' defined but not used
> > > [-Wunused-function]
> > >  static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
> > 
> > Please refer to [1], '__maybe_unused' can fix your problem.
> > 
> > [1]
> > http://lxr.free-electrons.com/source/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c#L76
> Add __maybe_unused just let GCC not produce a warning for this function.
> So you want add patch like this?
> 
> [PATCH v7 6/9] drm/mediatek: add dsi interrupt control
> +static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi
> *dsi, u32 irq_flag,
> 
> +static __maybe_unused void mtk_dsi_irq_data_set(struct mtk_dsi *dsi,
> u32 irq_bit)
> 
> [PATCH v7 7/9] drm/mediatek: add dsi transfer function
> -static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi
> *dsi, u32 irq_flag,
> +static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
> 
> -static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi,
> u32 irq_bit)
> +static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
> 
> Put the static function earlier and add __maybe_unused annotations.
> Then remove _maybe_unused annotations later.  Or you want to keep
> __maybe_unused annotations inside?  Sounds unnecessary, it is different
> from your reference sharp_panel_read().

Removing '__maybe_unused' in later patch looks good to me.

Regards,
CK

> 
> > 
> > Regards,
> > CK
> > 
> > > 
> > > > Regards,
> > > > CK
> > > > 
> > > > > 
> > > > > Regards,
> > > > > yt.shen
> > > > > > 
> > > > > > 
> > > > > > [1] https://patchwork.kernel.org/patch/9310819/
> > > > > > 
> > > > > > 
> > > > > > Regards,
> > > > > > CK
> > > > > > 
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 




Re: [PATCH v8 4/9] drm/mediatek: update display module connections

2016-09-13 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 20:01 +0800, YT Shen wrote:
> update connections for OVL, RDMA, BLS, DSI
> 
> Signed-off-by: YT Shen 
> ---

[snip...]

> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 53065c7..0850aa4 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -40,6 +40,7 @@ enum mtk_ddp_comp_type {
>  
>  enum mtk_ddp_comp_id {
>   DDP_COMPONENT_AAL,
> + DDP_COMPONENT_BLS,

I think this should be moved to an independent patch and title of it
should be "Add BLS component." If you keep it in this patch, title of
this patch should be modified as "Add BLS component and update display
module connections."

Regards,
CK

>   DDP_COMPONENT_COLOR0,
>   DDP_COMPONENT_COLOR1,
>   DDP_COMPONENT_DPI0,




Re: [PATCH v8 6/9] drm/mediatek: add dsi interrupt control

2016-09-13 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 20:01 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi interrupt control
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 78 
> ++
>  1 file changed, 78 insertions(+)
> 

[snip...]

>  
> +static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
> +{
> + u32 inten = DSI_INT_ALL_BITS;
> +
> + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO)
> + inten &= ~(TE_RDY_INT_FLAG | EXT_TE_RDY_INT_FLAG);
> +
> + writel(inten, dsi->regs + DSI_INTEN);
> +}
> +

[snip...]

> +
> +static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
> +{
> + struct mtk_dsi *dsi = dev_id;
> + u32 status, tmp;
> + u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;

Why do you only process these three irq? You also enable TE_RDY_INT_FLAG
& EXT_TE_RDY_INT_FLAG in mtk_dsi_set_interrupt_enable(). Process these
two irq here or not enable them in mtk_dsi_set_interrupt_enable().

Regards,
CK

> +
> + status = readl(dsi->regs + DSI_INTSTA) & flag;
> +
> + if (status) {
> + do {
> + mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
> + tmp = readl(dsi->regs + DSI_INTSTA);
> + } while (tmp & DSI_BUSY);
> +
> + mtk_dsi_mask(dsi, DSI_INTSTA, status, 0);
> + mtk_dsi_irq_data_set(dsi, status);
> + wake_up_interruptible(>irq_wait_queue);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +



Re: [PATCH v7 8/9] drm/mediatek: update DSI sub driver flow

2016-09-13 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 18:15 +0800, YT Shen wrote:
> Hi CK,
> 
> On Wed, 2016-09-07 at 12:58 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> > > This patch update enable/disable flow of DSI module and MIPI TX module
> > > 
> > > Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> > > Signed-off-by: YT Shen <yt.s...@mediatek.com>
> > > ---
> > 
> > I think the description is too simple. Please briefly describe WHY of
> > this patch. The original enable/disable flow is workable, so why do you
> > need this patch? Without this patch, what problem would happen?
> Got it, we will update more descriptions in the next version.
> There is no transfer/interrupt function in the upstream DSI driver.
> We also implement the following function [1][2] in this patch series.
> 
> Original flow works on there is a bridge chip: DSI -> bridge -> panel.
> In this case: DSI -> panel, the DSI sub driver flow should be updated.
> We need to initialize DSI first so that we can send commands to panel.
> 
> [1] https://patchwork.kernel.org/patch/9310819/
> drm/mediatek: add dsi interrupt control
> [2] https://patchwork.kernel.org/patch/9310823/
> drm/mediatek: add dsi transfer function
> 

I suggest you to separate "DSI directly connect to panel" related
patches to another series because MT8173 could also apply it and it is
not essential for MT2701 if MT2701 use bridge IC for dsi.

Regards,
CK

> > 
> > Regards,
> > CK
> > 
> > 
> 
> 




Re: [PATCH v7 9/9] drm/mediatek: add support for Mediatek SoC MT2701

2016-09-12 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 18:16 +0800, YT Shen wrote:
> Hi CK,
> 
> On Wed, 2016-09-07 at 13:37 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> > > This patch add support for the Mediatek MT2701 DISP subsystem.
> > > There is only one OVL engine in MT2701.
> > > 
> > > Signed-off-by: YT Shen <yt.s...@mediatek.com>
> > 
> > [snip...]
> > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> > > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > > index 4b4e449..465819b 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > > @@ -112,6 +112,7 @@ struct mtk_ddp_comp_match {
> > >  
> > >  static const struct mtk_ddp_comp_match 
> > > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> > >   [DDP_COMPONENT_AAL] = { MTK_DISP_AAL,   0, NULL },
> > > + [DDP_COMPONENT_BLS] = { MTK_DISP_PWM,   0, NULL },
> > 
> > I think BLS is different than PWM, so this statement should be
> > 
> > [DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL };
> The BLS module actually is a multifunction device, one of them is the
> PWM function.  We only upstream PWM function [1] now, and it is
> accepted.  When there are real use case (gamma function), we will update
> this part.  What do you think?

I think BLS = PWM + GAMMA and the device with register range from
0x1400a000 to 0x1400afff should be called BLS. I think this device is
called PWM in [1] because it just use its PWM function and it's not
suitable. At least in DRM driver, we should use the term BLS rather than
PWM. Maybe we should define as below:

[DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL };

and

{ .compatible = "mediatek,mt2701-disp-pwm",   .data = (void
*)MTK_DISP_BLS },


Regards,
CK

[1] https://patchwork.kernel.org/patch/9223001/

> 
> Regards,
> yt.shen
> 
> [1] https://patchwork.kernel.org/patch/9223001/
> 
> > 
> > 
> > >   [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR, 0, _color },
> > >   [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR, 1, _color },
> > >   [DDP_COMPONENT_DPI0]= { MTK_DPI,0, NULL },
> > 
> > Regards,
> > CK
> > 
> > 
> 
> 




Re: [PATCH v7 7/9] drm/mediatek: add dsi transfer function

2016-09-13 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 18:16 +0800, YT Shen wrote:
> Hi CK,
> 
> On Wed, 2016-09-07 at 10:33 +0800, CK Hu wrote:
> > Hi, YT:
> > 
> > On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> > > From: shaoming chen <shaoming.c...@mediatek.com>
> > > 
> > > add dsi read/write commands for transfer function
> > > 
> > > Signed-off-by: shaoming chen <shaoming.c...@mediatek.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_dsi.c | 188 
> > > +
> > >  1 file changed, 188 insertions(+)
> > > 
> > 
> > [snip...]
> > 
> > >  
> > > +static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
> > > +{
> > > + dsi->irq_data &= ~irq_bit;
> > > +}
> > > +
> > 
> > [snip...]
> > 
> > > +
> > > +static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
> > > +  unsigned int timeout)
> > > +{
> > > + s32 ret = 0;
> > > + unsigned long jiffies = msecs_to_jiffies(timeout);
> > > +
> > > + ret = wait_event_interruptible_timeout(_dsi_irq_wait_queue,
> > > +dsi->irq_data & irq_flag,
> > > +jiffies);
> > > + if (ret == 0) {
> > > + dev_info(dsi->dev, "Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
> > > +
> > > + mtk_dsi_enable(dsi);
> > > + mtk_dsi_reset_engine(dsi);
> > > + }
> > > +
> > > + return ret;
> > > +}
> > 
> > I think mtk_dsi_irq_data_clear() and mtk_dsi_wait_for_irq_done() should
> > be moved to the 6th patch [1] of this series because these two functions
> > deal the irq control.
> We will move mtk_dsi_irq_data_clear() to patch "drm/mediatek: add dsi
> interrupt control" and put mtk_dsi_wait_for_irq_done() here, because it
> is used in the transfer function.

mtk_dsi_irq_data_clear() is also only used in transfer function now. I
think both function could be used for other application rather than
transfer function, so these two function are general function for irq
control.

Regards,
CK

> 
> Regards,
> yt.shen
> > 
> > 
> > [1] https://patchwork.kernel.org/patch/9310819/
> > 
> > 
> > Regards,
> > CK
> > 
> 
> 




Re: [PATCH v14 2/4] CMDQ: Mediatek CMDQ driver

2016-09-29 Thread CK Hu
Hi, HS:

On Mon, 2016-09-05 at 09:44 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao <hs.l...@mediatek.com>
> Signed-off-by: CK Hu <ck...@mediatek.com>
> ---

[snip...]

> +
> +struct cmdq_task {
> + struct cmdq *cmdq;
> + struct list_headlist_entry;
> + void*va_base;
> + dma_addr_t  pa_base;
> + size_t  cmd_buf_size; /* command occupied size */
> + size_t  buf_size; /* real buffer size */
> + boolfinalized;
> + struct cmdq_thread  *thread;

I think thread info could be removed from cmdq_task. Only
cmdq_task_handle_error() and cmdq_task_insert_into_thread() use
task->thread and caller of both function has the thread info. So you
could just pass thread info into these two function and remove thread
info in cmdq_task.

> + struct cmdq_task_cb cb;

I think this callback function is equal to mailbox client tx_done
callback. It's better to use already-defined interface rather than
creating your own.

> +};
> +

[snip...]

> +
> +static int cmdq_suspend(struct device *dev)
> +{
> + struct cmdq *cmdq = dev_get_drvdata(dev);
> + struct cmdq_thread *thread;
> + int i;
> + bool task_running = false;
> +
> + mutex_lock(>task_mutex);
> + cmdq->suspended = true;
> + mutex_unlock(>task_mutex);
> +
> + for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
> + thread = >thread[i];
> + if (!list_empty(>task_busy_list)) {
> + mod_timer(>timeout, jiffies + 1);
> + task_running = true;
> + }
> + }
> +
> + if (task_running) {
> + dev_warn(dev, "exist running task(s) in suspend\n");
> + msleep(20);

Why sleep here? It looks like a recovery but could 20ms recovery
something? I think warning message is enough because you see the warning
message, and you fix the bug, so no need to recovery anything.

> + }
> +
> + clk_unprepare(cmdq->clock);
> + return 0;
> +}
> +

Regards,
CK




Re: [PATCH v14 2/4] CMDQ: Mediatek CMDQ driver

2016-09-30 Thread CK Hu
Hi, HS:

One comment inline

On Fri, 2016-09-30 at 16:56 +0800, Horng-Shyang Liao wrote:
> Hi CK,
> 
> Please see my inline reply.
> 
> On Fri, 2016-09-30 at 11:06 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > On Mon, 2016-09-05 at 09:44 +0800, HS Liao wrote:
> > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > CMDQ is used to help write registers with critical time limitation,
> > > such as updating display configuration during the vblank. It controls
> > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > Currently, CMDQ only supports display related hardwares, but we expect
> > > it can be extended to other hardwares for future requirements.
> > > 
> > > Signed-off-by: HS Liao <hs.l...@mediatek.com>
> > > Signed-off-by: CK Hu <ck...@mediatek.com>
> > > ---
> > 
> > [snip...]
> > 
> > > +
> > > +struct cmdq_task {
> > > + struct cmdq *cmdq;
> > > + struct list_headlist_entry;
> > > + void*va_base;
> > > + dma_addr_t  pa_base;
> > > + size_t  cmd_buf_size; /* command occupied size */
> > > + size_t  buf_size; /* real buffer size */
> > > + boolfinalized;
> > > + struct cmdq_thread  *thread;
> > 
> > I think thread info could be removed from cmdq_task. Only
> > cmdq_task_handle_error() and cmdq_task_insert_into_thread() use
> > task->thread and caller of both function has the thread info. So you
> > could just pass thread info into these two function and remove thread
> > info in cmdq_task.
> 
> This modification will remove 1 pointer but add 2 pointers. Moreover,
> more pointers will need to be delivered between functions for future
> extension. IMHO, it would be better to keep thread pointer inside
> cmdq_task.
> 
> > > + struct cmdq_task_cb cb;
> > 
> > I think this callback function is equal to mailbox client tx_done
> > callback. It's better to use already-defined interface rather than
> > creating your own.
> 
> This is because CMDQ driver allows different callback functions for
> different tasks, but mailbox only allows one callback function per
> channel. But, I think I can add a wrapper for tx_done to call CMDQ
> callback functions. So, I will use tx_done in CMDQ v15.

Up to now, one callback function for one channel is enough for DRM. So
'different callback function for different sent-message' looks like an
advanced function. Maybe you should not include it in first patch. 

Regards,
CK

> 
> > > +};
> > > +
> > 
> > [snip...]
> > 
> > > +
> > > +static int cmdq_suspend(struct device *dev)
> > > +{
> > > + struct cmdq *cmdq = dev_get_drvdata(dev);
> > > + struct cmdq_thread *thread;
> > > + int i;
> > > + bool task_running = false;
> > > +
> > > + mutex_lock(>task_mutex);
> > > + cmdq->suspended = true;
> > > + mutex_unlock(>task_mutex);
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
> > > + thread = >thread[i];
> > > + if (!list_empty(>task_busy_list)) {
> > > + mod_timer(>timeout, jiffies + 1);
> > > + task_running = true;
> > > + }
> > > + }
> > > +
> > > + if (task_running) {
> > > + dev_warn(dev, "exist running task(s) in suspend\n");
> > > + msleep(20);
> > 
> > Why sleep here? It looks like a recovery but could 20ms recovery
> > something? I think warning message is enough because you see the warning
> > message, and you fix the bug, so no need to recovery anything.
> 
> My purpose is context switch to finish timer's work.
> I will replace it by schedule().
> 
> > > + }
> > > +
> > > + clk_unprepare(cmdq->clock);
> > > + return 0;
> > > +}
> > > +
> > 
> > Regards,
> > CK
> 
> Thanks,
> HS
> 
> 




Re: [PATCH v8 9/9] drm/mediatek: add support for Mediatek SoC MT2701

2016-09-18 Thread CK Hu
Hi, YT:

On Mon, 2016-09-12 at 20:01 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  6 ++
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  6 ++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 17 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  7 +++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 29 
> +
>  drivers/gpu/drm/mediatek/mtk_dsi.c  |  1 +
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c  |  6 ++
>  7 files changed, 72 insertions(+)
> 

[snip...]

> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 4b4e449..465819b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -112,6 +112,7 @@ struct mtk_ddp_comp_match {
>  
>  static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] 
> = {
>   [DDP_COMPONENT_AAL] = { MTK_DISP_AAL,   0, NULL },
> + [DDP_COMPONENT_BLS] = { MTK_DISP_PWM,   0, NULL },

I would like to move this modification to the patch of "Add BLS
component". Just like 'shadow register', even we first introduce it in
MT2701, we separate it in another independent patch because it may be
included in other Mediatek Soc. I prefer modification of this patch is
something which exist in MT8173 but is different in MT2701. 

Regards,
CK

>   [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR, 0, _color },
>   [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR, 1, _color },
>   [DDP_COMPONENT_DPI0]= { MTK_DPI,0, NULL },
> @@ -130,11 +131,17 @@ static const struct mtk_ddp_comp_match 
> mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>   [DDP_COMPONENT_WDMA1]   = { MTK_DISP_WDMA,  1, NULL },
>  };
>  



Re: [PATCH v7 9/9] drm/mediatek: add support for Mediatek SoC MT2701

2016-09-06 Thread CK Hu
Hi, YT:

On Fri, 2016-09-02 at 19:24 +0800, YT Shen wrote:
> This patch add support for the Mediatek MT2701 DISP subsystem.
> There is only one OVL engine in MT2701.
> 
> Signed-off-by: YT Shen 

[snip...]

> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 4b4e449..465819b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -112,6 +112,7 @@ struct mtk_ddp_comp_match {
>  
>  static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] 
> = {
>   [DDP_COMPONENT_AAL] = { MTK_DISP_AAL,   0, NULL },
> + [DDP_COMPONENT_BLS] = { MTK_DISP_PWM,   0, NULL },

I think BLS is different than PWM, so this statement should be

[DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL };


>   [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR, 0, _color },
>   [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR, 1, _color },
>   [DDP_COMPONENT_DPI0]= { MTK_DPI,0, NULL },

Regards,
CK




Re: [PATCH 2/2] drm/mediatek: clear IRQ status before enable OVL interrupt

2016-09-28 Thread CK Hu
Acked-by: CK Hu <ck...@mediatek.com>

On Thu, 2016-09-29 at 11:29 +0800, Bibby Hsieh wrote:
> To make sure that the first vblank IRQ after enabling
> vblank isn't too short or immediate, we have to clear
> the IRQ status before enable OVL interrupt.
> 
> Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 019b7ca..f75c5b5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -80,6 +80,7 @@ static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
>ddp_comp);
>  
>   priv->crtc = crtc;
> + writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
>   writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
>  }
>  




Re: [PATCH 1/2] drm/mediatek: set vblank_disable_allowed to true

2016-09-28 Thread CK Hu
Acked-by: CK Hu <ck...@mediatek.com>

On Thu, 2016-09-29 at 11:29 +0800, Bibby Hsieh wrote:
> MTK DRM driver didn't set the vblank_disable_allowed to
> true, it cause that the irq_handler is called every
> 16.6 ms (every vblank) when the display didn't be updated.
> 
> Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index eebb7d8..941ec5f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -200,6 +200,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>   if (ret < 0)
>   goto err_component_unbind;
>  
> + drm->vblank_disable_allowed = true;
>   drm_kms_helper_poll_init(drm);
>   drm_mode_config_reset(drm);
>  




Re: drm/mediatek: fixed the calc method of data rate per lane

2016-09-29 Thread CK Hu
Hi, Jitao:

Sorry for late reply.
Some comments inline.

On Fri, 2016-08-26 at 14:10 +0800, Jitao Shi wrote:
> Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e. Tlpx,
> Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP mode, this
> signal will cause h-time larger than normal and reduce FPS.
> Need to multiply a coefficient to offset the extra signal's effect.
> coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+Ths_trail+
> Ths_exit)/(htotal*bpp/lane_number))
> 
> Signed-off-by: Jitao Shi 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  111 
> ++--
>  1 file changed, 67 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 28b2044..506aa22 100644

[snip...]

>  
> -static void dsi_phy_timconfig(struct mtk_dsi *dsi)
> +static void dsi_phy_timconfig(struct mtk_dsi *dsi, u32 phy_timing0,
> +   u32 phy_timing1, u32 phy_timing2,
> +   u32 phy_timing3)
>  {
> - u32 timcon0, timcon1, timcon2, timcon3;
> - unsigned int ui, cycle_time;
> - unsigned int lpx;
> -
> - ui = 1000 / dsi->data_rate + 0x01;
> - cycle_time = 8000 / dsi->data_rate + 0x01;
> - lpx = 5;
> -
> - timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
> - timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
> -   (4 * lpx);
> - timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
> -   (NS_TO_CYCLE(0x150, cycle_time) << 16);
> - timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
> -NS_TO_CYCLE(0x40, cycle_time);
> -
> - writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
> - writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> - writel(timcon2, dsi->regs + DSI_PHY_TIMECON2);
> - writel(timcon3, dsi->regs + DSI_PHY_TIMECON3);
> + writel(phy_timing0, dsi->regs + DSI_PHY_TIMECON0);
> + writel(phy_timing1, dsi->regs + DSI_PHY_TIMECON1);
> + writel(phy_timing2, dsi->regs + DSI_PHY_TIMECON2);
> + writel(phy_timing3, dsi->regs + DSI_PHY_TIMECON3);
>  }
>  
>  static void mtk_dsi_enable(struct mtk_dsi *dsi)
> @@ -202,19 +186,57 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  {
>   struct device *dev = dsi->dev;
>   int ret;
> + u64 bit_clock, total_bits;
> + u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
> + u32 phy_timing0, phy_timing1, phy_timing2, phy_timing3;
>  
>   if (++dsi->refcount != 1)
>   return 0;
>  
> + phy_timing0 = LPX(5) | HS_PRPR(6) | HS_ZERO(10) | HS_TRAIL(8);
> + phy_timing1 = TA_GO(20) | TA_SURE(7) | TA_GET(25) | DA_HS_EXIT(7);
> + phy_timing2 = CLK_ZERO(38) | CLK_TRAIL(22);
> + phy_timing3 = CLK_HS_PRPR(8) | CLK_HS_POST(21) | CLK_HS_EXIT(10);

The original phy_timing2 and phy_timing3 is defined as

timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
  (NS_TO_CYCLE(0x150, cycle_time) << 16);
timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8
|
   NS_TO_CYCLE(0x40, cycle_time);

They are varied by cycle_time. I think you should not use a fixed value
for them.

> +
> + switch (dsi->format) {
> + case MIPI_DSI_FMT_RGB565:
> + bit_per_pixel = 16;
> + break;
> + case MIPI_DSI_FMT_RGB666_PACKED:
> + bit_per_pixel = 18;
> + break;
> + case MIPI_DSI_FMT_RGB666:
> + case MIPI_DSI_FMT_RGB888:
> + default:
> + bit_per_pixel = 24;
> + break;
> + }
>   /**
> -  * data_rate = (pixel_clock / 1000) * pixel_dipth * mipi_ratio;
> -  * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
> -  * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
> -  * we set mipi_ratio is 1.05.
> +  * data_rate = (pixel_clock) * bit_per_pixel * mipi_ratio / lane_num;
> +  * vm.pixelclock is Khz, data_rata unit is Hz, so need to multiply 1000
> +  * mipi_ratio is (htotal * byte_per_pixel / lane_num + Tlpx + Ths_prep
> +  *+ Thstrail + Ths_exit + Ths_zero) /
> +  *   (htotal * byte_per_pixel /lane_number)
>*/
> - dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
> + bit_clock = dsi->vm.pixelclock * 1000 * bit_per_pixel;
> + htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
> +  dsi->vm.hsync_len;
> + htotal_bits = htotal * bit_per_pixel;
> +
> + /**
> +  * overhead = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
> +  */
> + overhead_cycles = (phy_timing0 & 0xff) + (phy_timing0 >> 8 & 0xff) +
> +   (phy_timing0 >> 16 & 0xff) +
> +   (phy_timing0 >> 24 & 0xff) +
> +   (phy_timing1 >> 24 & 0xff);


Re: [PATCH] drm/mediatek: fix a typo

2016-09-28 Thread CK Hu
Acked-by: CK Hu <ck...@mediatek.com>

On Thu, 2016-09-29 at 11:22 +0800, Bibby Hsieh wrote:
> Fix the typo: OD_RELAYMODE->OD_CFG
> 
> Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index df33b3c..aa5f20f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -123,7 +123,7 @@ static void mtk_od_config(struct mtk_ddp_comp *comp, 
> unsigned int w,
> unsigned int bpc)
>  {
>   writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
> - writel(OD_RELAYMODE, comp->regs + OD_RELAYMODE);
> + writel(OD_RELAYMODE, comp->regs + OD_CFG);
>   mtk_dither_set(comp, bpc, DISP_OD_CFG);
>  }
>  




Re: [PATCH v5 0/3] MT8173 HDMI 4K support

2016-10-17 Thread CK Hu
On Thu, 2016-09-29 at 11:02 +0800, Bibby Hsieh wrote:
> This is MT8173 HDMI 4K support PATCH v5, based on 4.8-rc1.
> 
> In order to support HDMI 4K on MT8173,
> we have to make some modifications.
> 1) Make sure that mtk_hdmi_send_infoframe is sent successfully.
> 2) Enhance the HDMI driving current to improve performance.
> 3) Make sure that pixel clock is 297MHz when resolution is 4K.
> 

For this series,
Acked-by: CK Hu <ck...@mediatek.com>

> Changes since v4:
>  - Update commit message and patch title.
> 
> Changes since v3:
>  - Rebase to 4.8-rc1.
>  - The valid range of tvdpll is 1G to 2G Hz, so, we Change the
>if statement of mode->clock to fit that and add a comment.
> 
> Changes since v2:
>  - Remove the change about preparation for MT2701 support.
> 
> Changes since v1:
>  - According to the suggestion from philipp, We use the new
>dpi0_sel rate set method.
>  - calls clk_set_rate to set the dpi0_sel according to the
>pixel clock.
>  - Remove the direct access to all the intermediate clock part.
>  - Remove the intermediate tvdpll_d* clocks in dts.
>  - According to suggestion from CK, we rename the clock parse
>function and remove it from mtk_dpi_conf struct.
>  - Merges the hdmi Pll set rate for pixel clock greater than
>165MHz and smaller parts.
> 
> The PATCH depends on the following patch:
> https://patchwork.kernel.org/patch/9262575/
> (arm64: dts: mt8173: add mmsel clocks for 4K support)
> 
> Junzhi Zhao (3):
>   drm/mediatek: do mtk_hdmi_send_infoframe after HDMI clock enable
>   drm/mediatek: enhance the HDMI driving current
>   drm/mediatek: modify the factor to make the pll_rate set in the 1G-2G
> range
> 
>  drivers/gpu/drm/mediatek/mtk_dpi.c |9 +++--
>  drivers/gpu/drm/mediatek/mtk_hdmi.c|   17 ++
>  drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c |   42 
> +---
>  3 files changed, 48 insertions(+), 20 deletions(-)
> 




Re: [PATCH v2] drm/mediatek: fix a typo

2016-10-18 Thread CK Hu
Acked-by: CK Hu <ck...@mediatek.com>

On Tue, 2016-10-18 at 16:23 +0800, Bibby Hsieh wrote:
> If we want to set the hardware OD to relay mode,
> we have to set OD_CFG register rather than
> OD_RELAYMODE; otherwise, the system will access
> the wrong address.
> 
> Fixes: 7216436420414144646f5d8343d061355fd23483 ("drm/mediatek: set mt8173 
> dithering function")
> Cc: sta...@vger.kernel.org # v4.9+
> Signed-off-by: Bibby Hsieh <bibby.hs...@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index df33b3c..aa5f20f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -123,7 +123,7 @@ static void mtk_od_config(struct mtk_ddp_comp *comp, 
> unsigned int w,
> unsigned int bpc)
>  {
>   writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
> - writel(OD_RELAYMODE, comp->regs + OD_RELAYMODE);
> + writel(OD_RELAYMODE, comp->regs + OD_CFG);
>   mtk_dither_set(comp, bpc, DISP_OD_CFG);
>  }
>  




Re: [PATCH v9 00/10] MT2701 DRM support

2016-11-13 Thread CK Hu
Hi, YT:

On Fri, 2016-11-11 at 19:55 +0800, YT Shen wrote:
> This is MT2701 DRM support PATCH v9, based on 4.9-rc1.
> We add DSI interrupt control, transfer function for MIPI DSI panel support.
> Most codes are the same, except some register changed.
> 
> For example:
>  - DISP_OVL address offset changed, color format definition changed.
>  - DISP_RDMA fifo size changed.
>  - DISP_COLOR offset changed.
>  - MIPI_TX setting changed.
> 
> We add a new component DDP_COMPONENT_BLS, and the connections are updated.
> OVL -> RDMA -> COLOR -> BLS -> DSI
> RDMA -> DPI
> And we have shadow register support in MT2701.
> 
> We remove dts patch from the patch series, which depends on MT2701 CCF and 
> scpsys.

For this series, it looks good to me.
Acked-by: CK Hu <ck...@mediatek.com>

> 
> Changes since v8:
> - enable 3 DSI interrupts only
> - move mtk_dsi_wait_for_irq_done() to the patch of irq control
> - use the name BLS in DRM driver part
> - move BLS declaration to a separate patch
> - update mtk_dsi_switch_to_cmd_mode()
> - update mtk_output_dsi_enable() and mtk_output_dsi_disable()
> 
> Changes since v7:
> - Remove redundant codes
> - Move the definition of DDP_COMPONENT_BLS to patch of "drm/mediatek: update 
> display module connections"
> - Move _dsi_irq_wait_queue into platform driver data
> - Move mtk_dsi_irq_data_clear() to patch of "drm/mediatek: add dsi interrupt 
> control"
> - Add more descriptions in the commit messages
> 
> Changes since v6:
> - Change data type of irq_data to u32
> - Rewrite mtk_dsi_host_transfer() for simplify
> - Move some MIPI_TX config to patch of "drm/mediatek: add *driver_data for 
> different hardware settings".
> - Remove device tree from this patch series
> 
> Changes since v5:
> - Remove DPI device tree and compatible string
> - Use one wait queue to handle interrupt status
> - Update the interrupt check flow and DSI_INT_ALL_BITS
> - Use same function for host read/write command
> - various fixes
> 
> Changes since v4:
> - Add messages when timeout in mtk_disp_mutex_acquire()
> - Add descriptions for DISP_REG_MUTEX registers
> - Move connection settings for display modules to a separate patch
> - Remove 'mt2701-disp-wdma' because it is unused
> - Move cleaning up and renaming to a separate patch
> - Use wait_event_interruptible_timeout() to replace polling
> - Remove irq_num from mtk_dsi structure
> - Remove redundant and debug codes
> 
> Changes since v3:
> - Add DSI support for MIPI DSI panels
> - Update BLS binding to PWM nodes
> - Remove ufoe device nodes
> - Remove redundant parentheses
> - Remove global variable initialization
> 
> Changes since v2:
> - Rename mtk_ddp_mux_sel to mtk_ddp_sout_sel
> - Update mt2701_mtk_ddp_ext components
> - Changed to prefix naming
> - Reorder the patch series
> - Use of_device_get_match_data() to get driver private data
> - Use iopoll macros to implement mtk_disp_mutex_acquire()
> - Removed empty device tree nodes
> 
> Changes since v1:
> - Removed BLS bindings and codes, which belong to pwm driver
> - Moved mtk_disp_mutex_acquire() just before mtk_crtc_ddp_config()
> - Split patch into smaller parts
> - Added const keyword to constant structure
> - Removed codes for special memory align
> 
> Thanks,
> yt.shen
> 
> YT Shen (8):
>   drm/mediatek: rename macros, add chip prefix
>   drm/mediatek: add *driver_data for different hardware settings
>   drm/mediatek: add shadow register support
>   drm/mediatek: add BLS component
>   drm/mediatek: update display module connections
>   drm/mediatek: cleaning up and refine
>   drm/mediatek: update DSI sub driver flow for sending commands to panel
>   drm/mediatek: add support for Mediatek SoC MT2701
> 
> shaoming chen (2):
>   drm/mediatek: add dsi interrupt control
>   drm/mediatek: add dsi transfer function
> 
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  33 ++-
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  17 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  76 +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 138 ++---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |   2 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  38 ++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  15 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  54 +++-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   9 +
>  drivers/gpu/drm/mediatek/mtk_dsi.c  | 429 
> 
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c  |  70 +++--
>  11 files changed, 715 insertions(+), 166 deletions(-)
> 




Re: [PATCH v5] drm/mediatek: fixed the calc method of data rate per lane

2016-11-16 Thread CK Hu
Hi, Jitao:


On Wed, 2016-11-16 at 11:20 +0800, Jitao Shi wrote:
> Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e.
> Tlpx, Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP
> mode, those signals will cause h-time larger than normal and reduce FPS.
> So need to multiply a coefficient to offset the extra signal's effect.
>   coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+
>Ths_trail+Ths_exit)/(htotal*bpp/lane_number)
> 
> Signed-off-by: Jitao Shi 

It looks good to me.
But this patch conflict with [1] which is one patch of MT2701 series. I
want to apply MT2701 patches first, so please help to refine this patch
based on MT2701 patches.

[1] https://patchwork.kernel.org/patch/9422821/

Regards,
CK

> ---
> Change since v4:
>  - tune the calc comment more clear.
>  - define the phy timings as constants.
> 
> Chnage since v3:
>  - wrapp the commit msg.
>  - fix alignment of some lines. 
> 
> Change since v2:
>  - move phy timing back to dsi_phy_timconfig.
> 
> Change since v1:
>  - phy_timing2 and phy_timing3 refer clock cycle time.
>  - define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET 
> DA_HS_EXIT.
> ---
>  



Re: DRM: urgent v4.9-rc6 build regression: master build: 2 failures 1 warnings (v4.9-rc5-213-g961b708)

2016-11-17 Thread CK Hu
Hi, Arnd:

I've made a mistake that I've tried to build these patches on v4.9-rc1,
but I does not set CONFIG_DRM_MEDIATEK=y, therefore I didn't find out
these build fails. Now I fix the config problem, and I think I should
build these patches on latest kernel version even though patch's owner
test on old kernel version. I wish this flow would make things better.

It's ok that you just revert these two patches. I've fixed build fail
and will request pull later.

Regards,
CK

On Thu, 2016-11-17 at 16:24 +0100, Arnd Bergmann wrote:
> On Thursday, November 17, 2016 8:50:05 PM CET Dave Airlie wrote:
> > 
> > Arnd could you send a git pull with the two reverts, with my Acked-by on
> > it? I won't be in a place to do it for 8-9hrs.
> 
> I don't think it's that urgent, as long as we make sure it's fixed in the
> next -rc. I've sent out the reverts as patches with a little more information
> in the changelog: it turns out that they are actually broken on linux-next 
> too,
> they had just not made it in there, and one of the two actually did build
> on older kernels.
> 
> I think what happened here is that the fixes were tested on a v4.4 kernel
> and blindly forward-ported. It probably makes sense to look at the
> entire series again in case another one of them is broken.
> 
> Philipp, Hu, Bibby, could one of you have another look?
> 
>   Arnd




Re: [PATCH v5] drm/mediatek: fixed the calc method of data rate per lane

2016-11-17 Thread CK Hu
Hi, Daniel:

On Fri, 2016-11-18 at 11:22 +0800, Daniel Kurtz wrote:
> Hi CK,
> 
> On Thu, Nov 17, 2016 at 1:36 PM, CK Hu <ck...@mediatek.com> wrote:
> > Hi, Jitao:
> >
> >
> > On Wed, 2016-11-16 at 11:20 +0800, Jitao Shi wrote:
> >> Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e.
> >> Tlpx, Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP
> >> mode, those signals will cause h-time larger than normal and reduce FPS.
> >> So need to multiply a coefficient to offset the extra signal's effect.
> >>   coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+
> >>Ths_trail+Ths_exit)/(htotal*bpp/lane_number)
> >>
> >> Signed-off-by: Jitao Shi <jitao@mediatek.com>
> >
> > It looks good to me.
> > But this patch conflict with [1] which is one patch of MT2701 series. I
> > want to apply MT2701 patches first, so please help to refine this patch
> > based on MT2701 patches.
> 
> I don't think the MT2701 DSI patches are quite ready yet (I just
> reviewed the one below).
> Can we instead land Jitao's small targeted change first, and then
> rebase the MT2701 series on top.
> 
> Thanks,
> -Dan


MT2701 series looks still have some defect to be fixed.
Therefore, I would apply this patch first.
Thanks for your help.

Regards,
CK

> >
> > [1] https://patchwork.kernel.org/patch/9422821/
> >
> > Regards,
> > CK
> >
> >> ---
> >> Change since v4:
> >>  - tune the calc comment more clear.
> >>  - define the phy timings as constants.
> >>
> >> Chnage since v3:
> >>  - wrapp the commit msg.
> >>  - fix alignment of some lines.
> >>
> >> Change since v2:
> >>  - move phy timing back to dsi_phy_timconfig.
> >>
> >> Change since v1:
> >>  - phy_timing2 and phy_timing3 refer clock cycle time.
> >>  - define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET 
> >> DA_HS_EXIT.
> >> ---
> >>
> >




Re: [PATCH v2] drm/mediatek: fixed the calc method of data rate per lane

2016-10-26 Thread CK Hu
Hi, Jitao:

On Tue, 2016-10-25 at 13:40 +0800, Jitao Shi wrote:
> Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e. Tlpx,
> Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP mode, this
> signal will cause h-time larger than normal and reduce FPS.
> Need to multiply a coefficient to offset the extra signal's effect.
> coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+Ths_trail+
> Ths_exit)/(htotal*bpp/lane_number))
> 
> Signed-off-by: Jitao Shi 
> ---
> Change since v1:
>  - phy_timing2 and phy_timing3 refer clock cycle time.
>  - define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET 
> DA_HS_EXIT
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  103 
> +++-
>  1 file changed, 67 insertions(+), 36 deletions(-)
> 

[snip...]

>  
> -static void dsi_phy_timconfig(struct mtk_dsi *dsi)
> +static void dsi_phy_timconfig(struct mtk_dsi *dsi, u32 phy_timing0,
> +   u32 phy_timing1, u32 phy_timing2,
> +   u32 phy_timing3)
>  {
> - u32 timcon0, timcon1, timcon2, timcon3;
> - unsigned int ui, cycle_time;
> - unsigned int lpx;
> -
> - ui = 1000 / dsi->data_rate + 0x01;
> - cycle_time = 8000 / dsi->data_rate + 0x01;
> - lpx = 5;
> -
> - timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
> - timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
> -   (4 * lpx);
> - timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
> -   (NS_TO_CYCLE(0x150, cycle_time) << 16);
> - timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
> -NS_TO_CYCLE(0x40, cycle_time);
> -
> - writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
> - writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> - writel(timcon2, dsi->regs + DSI_PHY_TIMECON2);
> - writel(timcon3, dsi->regs + DSI_PHY_TIMECON3);

Why do you move these calculation to mtk_dsi_poweron()? You can keep
calculation here and just do some modification.

Regards,
CK

> + writel(phy_timing0, dsi->regs + DSI_PHY_TIMECON0);
> + writel(phy_timing1, dsi->regs + DSI_PHY_TIMECON1);
> + writel(phy_timing2, dsi->regs + DSI_PHY_TIMECON2);
> + writel(phy_timing3, dsi->regs + DSI_PHY_TIMECON3);
>  }
>  
>  static void mtk_dsi_enable(struct mtk_dsi *dsi)
> @@ -202,19 +188,51 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  {
>   struct device *dev = dsi->dev;
>   int ret;
> + u64 bit_clock, total_bits;
> + u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
> + u32 phy_timing0, phy_timing1, phy_timing2, phy_timing3;
> + u32 ui, cycle_time;
>  
>   if (++dsi->refcount != 1)
>   return 0;
>  
> + switch (dsi->format) {
> + case MIPI_DSI_FMT_RGB565:
> + bit_per_pixel = 16;
> + break;
> + case MIPI_DSI_FMT_RGB666_PACKED:
> + bit_per_pixel = 18;
> + break;
> + case MIPI_DSI_FMT_RGB666:
> + case MIPI_DSI_FMT_RGB888:
> + default:
> + bit_per_pixel = 24;
> + break;
> + }
> + /**
> +  * data_rate = (pixel_clock) * bit_per_pixel * mipi_ratio / lane_num;
> +  * vm.pixelclock is Khz, data_rata unit is Hz, so need to multiply 1000
> +  * mipi_ratio is (htotal * byte_per_pixel / lane_num + Tlpx + Ths_prep
> +  *+ Thstrail + Ths_exit + Ths_zero) /
> +  *   (htotal * byte_per_pixel /lane_number)
> +  */
> + bit_clock = dsi->vm.pixelclock * 1000 * bit_per_pixel;
> + htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
> +  dsi->vm.hsync_len;
> + htotal_bits = htotal * bit_per_pixel;
> +
>   /**
> -  * data_rate = (pixel_clock / 1000) * pixel_dipth * mipi_ratio;
> -  * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
> -  * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
> -  * we set mipi_ratio is 1.05.
> +  * overhead = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
>*/
> - dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
> + overhead_cycles = LPX + (HS_PRPR >> 8) + (HS_ZERO >> 16) +
> +   (HS_TRAIL >> 24) + (DA_HS_EXIT >> 24);
> + overhead_bits = overhead_cycles * dsi->lanes * 8;
> + total_bits = htotal_bits + overhead_bits;
>  
> - ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 100);
> + dsi->data_rate = DIV_ROUND_UP_ULL(bit_clock * total_bits,
> +   htotal_bits * dsi->lanes);
> +
> + ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
>   if (ret < 0) {
>   dev_err(dev, "Failed to set data rate: %d\n", ret);
>   goto err_refcount;
> @@ -236,7 +254,20 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  
>   mtk_dsi_enable(dsi);
>   

Re: [PATCH v3] drm/mediatek: fixed the calc method of data rate per lane

2016-10-26 Thread CK Hu
Hi, Jitao:

On Wed, 2016-10-26 at 16:59 +0800, Jitao Shi wrote:
> Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e. Tlpx,
> Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP mode, this
> signal will cause h-time larger than normal and reduce FPS.
> Need to multiply a coefficient to offset the extra signal's effect.
> coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+Ths_trail+
> Ths_exit)/(htotal*bpp/lane_number))
> 

One check-patch warning in commit message:

WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description
(prefer a maximum 75 chars per line)
#7:
Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e.
Tlpx,

> Signed-off-by: Jitao Shi 
> ---
> Change since v2:
>  - move phy timing back to dsi_phy_timconfig.
> 
> Change since v1:
>  - phy_timing2 and phy_timing3 refer clock cycle time.
>  - define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET 
> DA_HS_EXIT
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |   74 
> +---
>  1 file changed, 51 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 28b2044..8b3b38a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -85,16 +85,16 @@
>  #define LD0_WAKEUP_ENBIT(2)
>  
>  #define DSI_PHY_TIMECON0 0x110
> -#define LPX  (0xff << 0)
> -#define HS_PRPR  (0xff << 8)
> -#define HS_ZERO  (0xff << 16)
> -#define HS_TRAIL (0xff << 24)
> +#define LPX  (5 << 0)
> +#define HS_PRPR  (6 << 8)
> +#define HS_ZERO  (10 << 16)
> +#define HS_TRAIL (8 << 24)
>  
>  #define DSI_PHY_TIMECON1 0x114
> -#define TA_GO(0xff << 0)
> -#define TA_SURE  (0xff << 8)
> -#define TA_GET   (0xff << 16)
> -#define DA_HS_EXIT   (0xff << 24)
> +#define TA_GO(20 << 0)
> +#define TA_SURE  (7 << 8)
> +#define TA_GET   (25 << 16)
> +#define DA_HS_EXIT   (7 << 24)
>  
>  #define DSI_PHY_TIMECON2 0x118
>  #define CONT_DET (0xff << 0)
> @@ -161,20 +161,18 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 
> offset, u32 mask, u32 data)
>  static void dsi_phy_timconfig(struct mtk_dsi *dsi)
>  {
>   u32 timcon0, timcon1, timcon2, timcon3;
> - unsigned int ui, cycle_time;
> - unsigned int lpx;
> + u32 ui, cycle_time;
>  
>   ui = 1000 / dsi->data_rate + 0x01;
>   cycle_time = 8000 / dsi->data_rate + 0x01;
> - lpx = 5;
>  
> - timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
> - timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
> -   (4 * lpx);
> + timcon0 = LPX | HS_PRPR | HS_ZERO | HS_TRAIL;
> + timcon1 = 4 * LPX | (3 * LPX / 2) << 8 | 5 * LPX << 16 | DA_HS_EXIT;
>   timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
> -   (NS_TO_CYCLE(0x150, cycle_time) << 16);
> - timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
> -NS_TO_CYCLE(0x40, cycle_time);
> +   (NS_TO_CYCLE(0x150, cycle_time) << 16);

I think this line may align to '(' in the right of '='.

> + timcon3 = (2 * LPX) << 16 |
> +   NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
> +   NS_TO_CYCLE(0x40, cycle_time);

I think these two lines may align to '(' in the right of '='.

Regards,
CK
 I. 
>  
>   writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
>   writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> @@ -202,19 +200,49 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  {
>   struct device *dev = dsi->dev;
>   int ret;
> + u64 bit_clock, total_bits;
> + u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
>  
>   if (++dsi->refcount != 1)
>   return 0;
>  
> + switch (dsi->format) {
> + case MIPI_DSI_FMT_RGB565:
> + bit_per_pixel = 16;
> + break;
> + case MIPI_DSI_FMT_RGB666_PACKED:
> + bit_per_pixel = 18;
> + break;
> + case MIPI_DSI_FMT_RGB666:
> + case MIPI_DSI_FMT_RGB888:
> + default:
> + bit_per_pixel = 24;
> + break;
> + }
>   /**
> -  * data_rate = (pixel_clock / 1000) * pixel_dipth * mipi_ratio;
> -  * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
> -  * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
> -  * we set mipi_ratio is 1.05.
> +  * data_rate = (pixel_clock) * bit_per_pixel * 

Re: [PATCH] drm/mediatek: fix null pointer dereference

2016-10-28 Thread CK Hu
Hi, Matthias:

Even though OVL HW would not be enabled before component_add() in
current design, your patch would be safe for any situation.

Acked-by CK Hu <ck...@mediatek.com>

Regards,
CK

On Wed, 2016-10-26 at 16:09 +0200, Matthias Brugger wrote:
> The probe function requests the interrupt before initializing
> the ddp component. Which leads to a null pointer dereference at boot.
> Fix this by requesting the interrput after all components got
> initialized properly.
> 
> Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC
> MT8173.")
> Signed-off-by: Matthias Brugger <matthias@gmail.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 019b7ca..1e78159 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -250,13 +250,6 @@ static int mtk_disp_ovl_probe(struct platform_device 
> *pdev)
>   if (irq < 0)
>   return irq;
>  
> - ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> -IRQF_TRIGGER_NONE, dev_name(dev), priv);
> - if (ret < 0) {
> - dev_err(dev, "Failed to request irq %d: %d\n", irq, ret);
> - return ret;
> - }
> -
>   comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_OVL);
>   if (comp_id < 0) {
>   dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
> @@ -272,6 +265,13 @@ static int mtk_disp_ovl_probe(struct platform_device 
> *pdev)
>  
>   platform_set_drvdata(pdev, priv);
>  
> + ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> +IRQF_TRIGGER_NONE, dev_name(dev), priv);
> + if (ret < 0) {
> + dev_err(dev, "Failed to request irq %d: %d\n", irq, ret);
> + return ret;
> + }
> +
>   ret = component_add(dev, _disp_ovl_component_ops);
>   if (ret)
>   dev_err(dev, "Failed to add component: %d\n", ret);




Re: [PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel

2016-11-29 Thread CK Hu
Hi, YT:

some comments inline.

On Fri, 2016-11-25 at 18:34 +0800, YT Shen wrote:
> This patch update enable/disable flow of DSI module.
> Original flow works on there is a bridge chip: DSI -> bridge -> panel.
> In this case: DSI -> panel, the DSI sub driver flow should be updated.
> We need to initialize DSI first so that we can send commands to panel.
> 
> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 101 
> +
>  1 file changed, 80 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index ded4202..0569f2e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -126,6 +126,10 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_VM_CMD_CON   0x130
> +#define VM_CMD_ENBIT(0)
> +#define TS_VFP_ENBIT(5)
> +
>  #define DSI_CMDQ00x180
>  #define CONFIG   (0xff << 0)
>  #define SHORT_PACKET 0
> @@ -249,7 +253,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>* mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
>* we set mipi_ratio is 1.05.
>*/
> - dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
> + dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
> + dsi->data_rate /= (dsi->lanes * 1000 * 10);

This looks like a bug fix that use lanes to calculate data rate.

> + DRM_DEBUG_DRIVER("set mipitx's data rate: %dMHz\n", dsi->data_rate);
>  
>   ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 100);
>   if (ret < 0) {
> @@ -333,16 +339,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
>   u32 vid_mode = CMD_MODE;
>  
>   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
> - vid_mode = SYNC_PULSE_MODE;
> -
> - if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
> - !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
> + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
>   vid_mode = BURST_MODE;
> + else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> + vid_mode = SYNC_PULSE_MODE;
> + else
> + vid_mode = SYNC_EVENT_MODE;
>   }
>  
>   writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
>  }
>  
> +static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
> +{
> + mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
> + mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
> +}
> +
>  static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
>  {
>   struct videomode *vm = >vm;
> @@ -480,6 +493,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
>   writel(1, dsi->regs + DSI_START);
>  }
>  
> +static void mtk_dsi_stop(struct mtk_dsi *dsi)
> +{
> + writel(0, dsi->regs + DSI_START);
> +}
> +
> +static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
> +{
> + writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
> +}
> +
>  static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
>  {
>   u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
> @@ -538,6 +561,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
>   return IRQ_HANDLED;
>  }
>  
> +static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 
> t)
> +{
> + mtk_dsi_irq_data_clear(dsi, irq_flag);
> + mtk_dsi_set_cmd_mode(dsi);
> +
> + if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
> + DRM_ERROR("failed to switch cmd mode\n");
> + return -ETIME;
> + } else {
> + return 0;
> + }
> +}
> +
>  static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  {
>   if (WARN_ON(dsi->refcount == 0))
> @@ -546,11 +582,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>   if (--dsi->refcount != 0)
>   return;
>  
> - mtk_dsi_lane0_ulp_mode_enter(dsi);
> - mtk_dsi_clk_ulp_mode_enter(dsi);
> -
> - mtk_dsi_disable(dsi);
> -
>   clk_disable_unprepare(dsi->engine_clk);
>   clk_disable_unprepare(dsi->digital_clk);
>  
> @@ -564,13 +595,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>   if (dsi->enabled)
>   return;
>  
> - if (dsi->panel) {
> - if (drm_panel_prepare(dsi->panel)) {
> - DRM_ERROR("failed to setup the panel\n");
> - return;
> - }
> - }
> -
>   ret = mtk_dsi_poweron(dsi);
>   if (ret < 0) {
>   DRM_ERROR("failed to power on dsi\n");
> @@ -578,21 +602,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>   }
>  
>   mtk_dsi_rxtx_control(dsi);
> + mtk_dsi_ps_control_vact(dsi);
> + 

Re: [PATCH v10 00/13] MT2701 DRM support

2016-11-30 Thread CK Hu
Hi, YT:

On Fri, 2016-11-25 at 18:34 +0800, YT Shen wrote:
> This is MT2701 DRM support PATCH v10, based on 4.9-rc1.
> We add DSI interrupt control, transfer function for MIPI DSI panel support.
> Most codes are the same, except some register changed.
> 
> For example:
>  - DISP_OVL address offset changed, color format definition changed.
>  - DISP_RDMA fifo size changed.
>  - DISP_COLOR offset changed.
>  - MIPI_TX setting changed.
> 
> We add a new component DDP_COMPONENT_BLS, and the connections are updated.
> OVL -> RDMA -> COLOR -> BLS -> DSI
> RDMA -> DPI
> And we have shadow register support in MT2701.
> 
> We remove dts patch from the patch series, which depends on MT2701 CCF and 
> scpsys.
> 

Some patches in this series conflict with Linux 4.9-rc7.
Once you send next patches, please base on Linux 4.9-rc7 or later
version.

Regards,
CK

> Changes since v9:
> - Split DSI patches into smaller parts
> - Use a real linux errno for return value
> - Add error handling in mtk_output_dsi_enable()
> - Remove unused changes and redundant delays
> - Add helpers and macros for configuration
> - Combine "drm/mediatek: rename macros, add chip prefix" and "drm/mediatek: 
> add *driver_data for different hardware setting"
> 
> Changes since v8:
> - enable 3 DSI interrupts only
> - move mtk_dsi_wait_for_irq_done() to the patch of irq control
> - use the name BLS in DRM driver part
> - move BLS declaration to a separate patch
> - update mtk_dsi_switch_to_cmd_mode()
> - update mtk_output_dsi_enable() and mtk_output_dsi_disable()
> 
> Changes since v7:
> - Remove redundant codes
> - Move the definition of DDP_COMPONENT_BLS to patch of "drm/mediatek: update 
> display module connections"
> - Move _dsi_irq_wait_queue into platform driver data
> - Move mtk_dsi_irq_data_clear() to patch of "drm/mediatek: add dsi interrupt 
> control"
> - Add more descriptions in the commit messages
> 
> Changes since v6:
> - Change data type of irq_data to u32
> - Rewrite mtk_dsi_host_transfer() for simplify
> - Move some MIPI_TX config to patch of "drm/mediatek: add *driver_data for 
> different hardware settings".
> - Remove device tree from this patch series
> 
> Changes since v5:
> - Remove DPI device tree and compatible string
> - Use one wait queue to handle interrupt status
> - Update the interrupt check flow and DSI_INT_ALL_BITS
> - Use same function for host read/write command
> - various fixes
> 
> Changes since v4:
> - Add messages when timeout in mtk_disp_mutex_acquire()
> - Add descriptions for DISP_REG_MUTEX registers
> - Move connection settings for display modules to a separate patch
> - Remove 'mt2701-disp-wdma' because it is unused
> - Move cleaning up and renaming to a separate patch
> - Use wait_event_interruptible_timeout() to replace polling
> - Remove irq_num from mtk_dsi structure
> - Remove redundant and debug codes
> 
> Changes since v3:
> - Add DSI support for MIPI DSI panels
> - Update BLS binding to PWM nodes
> - Remove ufoe device nodes
> - Remove redundant parentheses
> - Remove global variable initialization
> 
> Changes since v2:
> - Rename mtk_ddp_mux_sel to mtk_ddp_sout_sel
> - Update mt2701_mtk_ddp_ext components
> - Changed to prefix naming
> - Reorder the patch series
> - Use of_device_get_match_data() to get driver private data
> - Use iopoll macros to implement mtk_disp_mutex_acquire()
> - Removed empty device tree nodes
> 
> Changes since v1:
> - Removed BLS bindings and codes, which belong to pwm driver
> - Moved mtk_disp_mutex_acquire() just before mtk_crtc_ddp_config()
> - Split patch into smaller parts
> - Added const keyword to constant structure
> - Removed codes for special memory align
> 
> Thanks,
> yt.shen
> 
> YT Shen (11):
>   drm/mediatek: add helpers for coverting from the generic components
>   drm/mediatek: add *driver_data for different hardware settings
>   drm/mediatek: add shadow register support
>   drm/mediatek: add BLS component
>   drm/mediatek: update display module connections
>   drm/mediatek: cleaning up and refine
>   drm/mediatek: add mipi_tx data rate check
>   drm/mediatek: add dsi ulp mode control
>   drm/mediatek: add dsi rxtx control
>   drm/mediatek: update DSI sub driver flow for sending commands to panel
>   drm/mediatek: add support for Mediatek SoC MT2701
> 
> shaoming chen (2):
>   drm/mediatek: add dsi interrupt control
>   drm/mediatek: add dsi transfer function
> 
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  64 +++--
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  39 ++-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  76 +++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 138 ++---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |   2 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  41 ++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   7 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  54 +++-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   9 +
>  drivers/gpu/drm/mediatek/mtk_dsi.c  | 430 
> 

Re: [PATCH v10 11/13] drm/mediatek: add dsi rxtx control

2016-11-30 Thread CK Hu
Hi, YT:

On Fri, 2016-11-25 at 18:34 +0800, YT Shen wrote:
> add non-continuous clock mode and EOT packet control for dsi
> 

I think commit title should be 'drm/mediatek: add non-continuous clock
mode and EOT packet control for dsi', and commit message should describe
more information about this modification. For example, what is the
difference between with and without this patch. Does it fix any problem?

Regards,
CK

> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 01df829..ded4202 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -399,6 +399,9 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>   break;
>   }
>  
> + tmp_reg |= (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) << 6;
> + tmp_reg |= (dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET) >> 3;
> +
>   writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
>  }
>  




Re: [PATCH v10 09/13] drm/mediatek: add mipi_tx data rate check

2016-11-30 Thread CK Hu
Hi, YT:


On Fri, 2016-11-25 at 18:34 +0800, YT Shen wrote:
> modify data rate limitation (>lGbps/lane) for mipitx
> 

I think MT2701 DRM can work correctly without this patch.
Why do you put this patch in MT2701 series?
Maybe you can send this patch independently.

Regards,
CK

> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c 
> b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> index fd84914..1ef00ac 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
> @@ -177,7 +177,9 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
>  
>   dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
>  
> - if (mipi_tx->data_rate >= 5) {
> + if (mipi_tx->data_rate > 125000) {
> + return -EINVAL;
> + } else if (mipi_tx->data_rate >= 5) {
>   txdiv = 1;
>   txdiv0 = 0;
>   txdiv1 = 0;




Re: [PATCH v10 10/13] drm/mediatek: add dsi ulp mode control

2016-11-30 Thread CK Hu
Hi, YT:

On Fri, 2016-11-25 at 18:34 +0800, YT Shen wrote:
> modify dsi enter ultra low power mode method
> 

This looks like a power-saving patch. I think without this, MT2701 could
still work correctly. The commit message is too simple, please describe
why this patch is related to MT2701. If it is not related to MT2701,
move this patch out of MT2701 series and send it independently.

Regards,
CK

> Signed-off-by: shaoming chen 
> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index d03a0f1..01df829 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -289,7 +289,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
> - mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
> + mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, LC_ULPM_EN);
>  }
>  
>  static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
> @@ -302,7 +302,7 @@ static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi 
> *dsi)
>  static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
>  {
>   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
> - mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
> + mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, LD0_ULPM_EN);
>  }
>  
>  static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)




Re: [PATCH v11 02/12] drm/mediatek: add helpers for coverting from the generic components

2017-01-15 Thread CK Hu
On Wed, 2017-01-11 at 14:51 +0800, YT Shen wrote:
> define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_ovl'
> define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_rdma'
> 
> Signed-off-by: YT Shen <yt.s...@mediatek.com>

Acked-by CK Hu <ck...@mediatek.com>

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 15 +--
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 15 +--
>  2 files changed, 18 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index c703102..ce2759f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -57,6 +57,11 @@ struct mtk_disp_ovl {
>   struct drm_crtc *crtc;
>  };
>  
> +static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
> +{
> + return container_of(comp, struct mtk_disp_ovl, ddp_comp);
> +}
> +
>  static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
>  {
>   struct mtk_disp_ovl *priv = dev_id;
> @@ -76,20 +81,18 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void 
> *dev_id)
>  static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
> struct drm_crtc *crtc)
>  {
> - struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
> -  ddp_comp);
> + struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
>  
> - priv->crtc = crtc;
> + ovl->crtc = crtc;
>   writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
>   writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
>  }
>  
>  static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
>  {
> - struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
> -  ddp_comp);
> + struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
>  
> - priv->crtc = NULL;
> + ovl->crtc = NULL;
>   writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
>  }
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 0df05f9..21eff6f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -49,6 +49,11 @@ struct mtk_disp_rdma {
>   struct drm_crtc *crtc;
>  };
>  
> +static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
> +{
> + return container_of(comp, struct mtk_disp_rdma, ddp_comp);
> +}
> +
>  static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id)
>  {
>   struct mtk_disp_rdma *priv = dev_id;
> @@ -77,20 +82,18 @@ static void rdma_update_bits(struct mtk_ddp_comp *comp, 
> unsigned int reg,
>  static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp,
>  struct drm_crtc *crtc)
>  {
> - struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
> -   ddp_comp);
> + struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
>  
> - priv->crtc = crtc;
> + rdma->crtc = crtc;
>   rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
>RDMA_FRAME_END_INT);
>  }
>  
>  static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
>  {
> - struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
> -   ddp_comp);
> + struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
>  
> - priv->crtc = NULL;
> + rdma->crtc = NULL;
>   rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
>  }
>  




Re: [PATCH v2] drm/mediatek: separate color module to fixup error memory reallocation

2017-06-19 Thread CK Hu
On Fri, 2017-06-16 at 22:02 +0800, YT Shen wrote:
> Previous patch (c5f228ef6c drm/mediatek: add *driver_data for different
> hardware settings) calls devm_kfree() and then devm_kzalloc() to
> reallocate color module data structure.  But this reallocation cannnot
> guarantee the new address is unchanged, but the caller will use the
> old address, which is wrong.
> 
> Fix it by separate color module from general components, this patch
> separate color module to independent files, like mtk_disp_ovl.c and
> mtk_disp_rdma.c do
> 

Hi, YT:

Applied to my branch mediatek-drm-next-4.13. Thanks.

Regards,
CK

> Signed-off-by: YT Shen 
> ---
>  drivers/gpu/drm/mediatek/Makefile   |   3 +-
>  drivers/gpu/drm/mediatek/mtk_disp_color.c   | 176 
> 
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  80 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   6 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
>  5 files changed, 185 insertions(+), 81 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_color.c
> 
> diff --git a/drivers/gpu/drm/mediatek/Makefile 
> b/drivers/gpu/drm/mediatek/Makefile
> index bf2e5be..e37b55a 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -1,4 +1,5 @@
> -mediatek-drm-y := mtk_disp_ovl.o \
> +mediatek-drm-y := mtk_disp_color.o \
> +   mtk_disp_ovl.o \
> mtk_disp_rdma.o \
> mtk_drm_crtc.o \
> mtk_drm_ddp.o \
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_color.c
> new file mode 100644
> index 000..ef79a6d
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mtk_drm_crtc.h"
> +#include "mtk_drm_ddp_comp.h"
> +
> +#define DISP_COLOR_CFG_MAIN  0x0400
> +#define DISP_COLOR_START_MT2701  0x0f00
> +#define DISP_COLOR_START_MT8173  0x0c00
> +#define DISP_COLOR_START(comp)   
> ((comp)->data->color_offset)
> +#define DISP_COLOR_WIDTH(comp)   (DISP_COLOR_START(comp) 
> + 0x50)
> +#define DISP_COLOR_HEIGHT(comp)  (DISP_COLOR_START(comp) 
> + 0x54)
> +
> +#define COLOR_BYPASS_ALL BIT(7)
> +#define COLOR_SEQ_SELBIT(13)
> +
> +struct mtk_disp_color_data {
> + unsigned int color_offset;
> +};
> +
> +/**
> + * struct mtk_disp_color - DISP_COLOR driver structure
> + * @ddp_comp - structure containing type enum and hardware resources
> + * @crtc - associated crtc to report irq events to
> + */
> +struct mtk_disp_color {
> + struct mtk_ddp_comp ddp_comp;
> + struct drm_crtc *crtc;
> + const struct mtk_disp_color_data*data;
> +};
> +
> +static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
> +{
> + return container_of(comp, struct mtk_disp_color, ddp_comp);
> +}
> +
> +static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
> +  unsigned int h, unsigned int vrefresh,
> +  unsigned int bpc)
> +{
> + struct mtk_disp_color *color = comp_to_color(comp);
> +
> + writel(w, comp->regs + DISP_COLOR_WIDTH(color));
> + writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
> +}
> +
> +static void mtk_color_start(struct mtk_ddp_comp *comp)
> +{
> + struct mtk_disp_color *color = comp_to_color(comp);
> +
> + writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
> +comp->regs + DISP_COLOR_CFG_MAIN);
> + writel(0x1, comp->regs + DISP_COLOR_START(color));
> +}
> +
> +static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = {
> + .config = mtk_color_config,
> + .start = mtk_color_start,
> +};
> +
> +static int mtk_disp_color_bind(struct device *dev, struct device *master,
> +void *data)
> +{
> + struct mtk_disp_color *priv = dev_get_drvdata(dev);
> + struct drm_device *drm_dev = data;
> + int ret;
> +
> + ret = mtk_ddp_comp_register(drm_dev, >ddp_comp);
> + if (ret < 0) {
> + dev_err(dev, "Failed to register component %s: %d\n",
> + dev->of_node->full_name, ret);
> + return ret;
> + }
> +
> +   

Re: [PATCH v3] drm: mediatek: change the variable type of rdma threshold

2017-06-22 Thread CK Hu
On Thu, 2017-06-22 at 10:43 +0800, Bibby Hsieh wrote:
> For some greater resolution, the rdma threshold
> variable will overflow.
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 0df05f9..8540aaa 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -109,7 +109,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, 
> unsigned int width,
>   unsigned int height, unsigned int vrefresh,
>   unsigned int bpc)
>  {
> - unsigned int threshold;
> + unsigned long long threshold;
>   unsigned int reg;
>  
>   rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xfff, width);
> @@ -121,10 +121,11 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, 
> unsigned int width,
>* output threshold to 6 microseconds with 7/6 overhead to
>* account for blanking, and with a pixel depth of 4 bytes:
>*/
> - threshold = width * height * vrefresh * 4 * 7 / 100;
> + threshold = div_u64((unsigned long long)width * height * vrefresh *
> + 4 * 7, 100);
>   reg = RDMA_FIFO_UNDERFLOW_EN |
> RDMA_FIFO_PSEUDO_SIZE(SZ_8K) |
> -   RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
> +   RDMA_OUTPUT_VALID_FIFO_THRESHOLD(clamp_val(threshold, 0, 0x3ff0));

Hi, Bibby:

Please symbolize '0x3ff0'.

Regards,
CK

>   writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
>  }
>  




  1   2   3   4   5   6   >