Skip to contentSkip to conversation

drm/msm: preparation for WB/DSI connectors

PATCH Superseded Stephane Viau 2 participants 34 messages Mar 3, 2015 – Mar 24, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover drm/msm: preparation for WB/DSI connectors

WB and DSI support are in the pipe and will come out soon. Before that, we need to prepare the MDP5 driver so we can support these connectors.

Stephane Viau (4):
drm/msm/mdp5: Update generated header files drm/msm/mdp5: Enhance operation mode for pipeline configuration drm/msm/mdp5: Add START signal to kick off certain pipelines drm/msm/mdp5: Make the intf connection in config module

 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h     |  68 +++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |  10 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  13 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  70 ++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 326 +++++++++++++++++++++++++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  75 +++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  40 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     |  99 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |  49 ++++-
 9 files changed, 519 insertions(+), 231 deletions(-)
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#1 lore raw

PATCH 1/4 drm/msm/mdp5: Update generated header files

Prepare for pipeline operation mode configuration, in particular for DSI and WB modes.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 68 ++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 35 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +33 -35
index c276624..095a54c 100644
@@ -8,7 +8,7 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27229 bytes, from 2015-02-10 17:00:41)
+- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27094 bytes, from 2015-01-23 16:27:31)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2014-06-02 18:31:15)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml      (   2357 bytes, from 2015-01-23 16:20:19)
 
@@ -37,11 +37,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 
-enum mdp5_intf {
+enum mdp5_intf_type {
+	INTF_DISABLED = 0,
 	INTF_DSI = 1,
 	INTF_HDMI = 3,
 	INTF_LCDC = 5,
 	INTF_eDP = 9,
+	INTF_VIRTUAL = 100,
+	INTF_WB = 101,
 };
 
 enum mdp5_intfnum {
@@ -67,11 +70,11 @@ enum mdp5_pipe {
 
 enum mdp5_ctl_mode {
 	MODE_NONE = 0,
-	MODE_ROT0 = 1,
-	MODE_ROT1 = 2,
-	MODE_WB0 = 3,
-	MODE_WB1 = 4,
-	MODE_WFD = 5,
+	MODE_WB_0_BLOCK = 1,
+	MODE_WB_1_BLOCK = 2,
+	MODE_WB_0_LINE = 3,
+	MODE_WB_1_LINE = 4,
+	MODE_WB_2_LINE = 5,
 };
 
 enum mdp5_pack_3d {
@@ -144,30 +147,25 @@ enum mdp5_data_format {
 	DATA_FORMAT_YUV = 1,
 };
 
-#define MDP5_IRQ_INTF0_WB_ROT_COMP				0x00000001
-#define MDP5_IRQ_INTF1_WB_ROT_COMP				0x00000002
-#define MDP5_IRQ_INTF2_WB_ROT_COMP				0x00000004
-#define MDP5_IRQ_INTF3_WB_ROT_COMP				0x00000008
-#define MDP5_IRQ_INTF0_WB_WFD					0x00000010
-#define MDP5_IRQ_INTF1_WB_WFD					0x00000020
-#define MDP5_IRQ_INTF2_WB_WFD					0x00000040
-#define MDP5_IRQ_INTF3_WB_WFD					0x00000080
-#define MDP5_IRQ_INTF0_PING_PONG_COMP				0x00000100
-#define MDP5_IRQ_INTF1_PING_PONG_COMP				0x00000200
-#define MDP5_IRQ_INTF2_PING_PONG_COMP				0x00000400
-#define MDP5_IRQ_INTF3_PING_PONG_COMP				0x00000800
-#define MDP5_IRQ_INTF0_PING_PONG_RD_PTR				0x00001000
-#define MDP5_IRQ_INTF1_PING_PONG_RD_PTR				0x00002000
-#define MDP5_IRQ_INTF2_PING_PONG_RD_PTR				0x00004000
-#define MDP5_IRQ_INTF3_PING_PONG_RD_PTR				0x00008000
-#define MDP5_IRQ_INTF0_PING_PONG_WR_PTR				0x00010000
-#define MDP5_IRQ_INTF1_PING_PONG_WR_PTR				0x00020000
-#define MDP5_IRQ_INTF2_PING_PONG_WR_PTR				0x00040000
-#define MDP5_IRQ_INTF3_PING_PONG_WR_PTR				0x00080000
-#define MDP5_IRQ_INTF0_PING_PONG_AUTO_REF			0x00100000
-#define MDP5_IRQ_INTF1_PING_PONG_AUTO_REF			0x00200000
-#define MDP5_IRQ_INTF2_PING_PONG_AUTO_REF			0x00400000
-#define MDP5_IRQ_INTF3_PING_PONG_AUTO_REF			0x00800000
+#define MDP5_IRQ_WB_0_DONE					0x00000001
+#define MDP5_IRQ_WB_1_DONE					0x00000002
+#define MDP5_IRQ_WB_2_DONE					0x00000010
+#define MDP5_IRQ_PING_PONG_0_DONE				0x00000100
+#define MDP5_IRQ_PING_PONG_1_DONE				0x00000200
+#define MDP5_IRQ_PING_PONG_2_DONE				0x00000400
+#define MDP5_IRQ_PING_PONG_3_DONE				0x00000800
+#define MDP5_IRQ_PING_PONG_0_RD_PTR				0x00001000
+#define MDP5_IRQ_PING_PONG_1_RD_PTR				0x00002000
+#define MDP5_IRQ_PING_PONG_2_RD_PTR				0x00004000
+#define MDP5_IRQ_PING_PONG_3_RD_PTR				0x00008000
+#define MDP5_IRQ_PING_PONG_0_WR_PTR				0x00010000
+#define MDP5_IRQ_PING_PONG_1_WR_PTR				0x00020000
+#define MDP5_IRQ_PING_PONG_2_WR_PTR				0x00040000
+#define MDP5_IRQ_PING_PONG_3_WR_PTR				0x00080000
+#define MDP5_IRQ_PING_PONG_0_AUTO_REF				0x00100000
+#define MDP5_IRQ_PING_PONG_1_AUTO_REF				0x00200000
+#define MDP5_IRQ_PING_PONG_2_AUTO_REF				0x00400000
+#define MDP5_IRQ_PING_PONG_3_AUTO_REF				0x00800000
 #define MDP5_IRQ_INTF0_UNDER_RUN				0x01000000
 #define MDP5_IRQ_INTF0_VSYNC					0x02000000
 #define MDP5_IRQ_INTF1_UNDER_RUN				0x04000000
@@ -202,25 +200,25 @@ static inline uint32_t MDP5_MDP_VERSION_MAJOR(uint32_t val)
 #define REG_MDP5_DISP_INTF_SEL					0x00000104
 #define MDP5_DISP_INTF_SEL_INTF0__MASK				0x000000ff
 #define MDP5_DISP_INTF_SEL_INTF0__SHIFT				0
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF0__SHIFT) & MDP5_DISP_INTF_SEL_INTF0__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF1__MASK				0x0000ff00
 #define MDP5_DISP_INTF_SEL_INTF1__SHIFT				8
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF1__SHIFT) & MDP5_DISP_INTF_SEL_INTF1__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF2__MASK				0x00ff0000
 #define MDP5_DISP_INTF_SEL_INTF2__SHIFT				16
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF2__SHIFT) & MDP5_DISP_INTF_SEL_INTF2__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF3__MASK				0xff000000
 #define MDP5_DISP_INTF_SEL_INTF3__SHIFT				24
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF3__SHIFT) & MDP5_DISP_INTF_SEL_INTF3__MASK;
 }
Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#2 lore raw

PATCH 1/1 rnndb: Prepare for more interfaces support (WB, DSI)

More interfaces are soon coming into picture; rework the interface type a bit in order to make the code more clear. Ping Pong interrupts are not directly linked to an interface number. This change removes the INTFn prefix for Ping Pong interrupts. Also rename some fields linked to WB paths.

---
 rnndb/mdp/mdp5.xml | 67 +++++++++++++++++++++++++++---------------------------
 1 file changed, 33 insertions(+), 34 deletions(-)
rnndb/mdp/mdp5.xml +33 -34
index 3c199a1..4d9781c 100644
@@ -11,11 +11,15 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 
 <domain name="MDP5" width="32">
 
-	<enum name="mdp5_intf">
+	<enum name="mdp5_intf_type">
+		<value name="INTF_DISABLED" value="0x0"/>
 		<value name="INTF_DSI"  value="0x1"/>
 		<value name="INTF_HDMI" value="0x3"/>
 		<value name="INTF_LCDC" value="0x5"/>
 		<value name="INTF_eDP"  value="0x9"/>
+		<value name="INTF_VIRTUAL"  value="0x64"/>
+		<!-- non-display interfaces are listed below: -->
+		<value name="INTF_WB"  value="0x65"/>
 	</enum>
 
 	<enum name="mdp5_intfnum">
@@ -44,11 +48,11 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 
 	<enum name="mdp5_ctl_mode">
 		<value name="MODE_NONE" value="0"/>
-		<value name="MODE_ROT0" value="1"/>
-		<value name="MODE_ROT1" value="2"/>
-		<value name="MODE_WB0" value="3"/>
-		<value name="MODE_WB1" value="4"/>
-		<value name="MODE_WFD" value="5"/>
+		<value name="MODE_WB_0_BLOCK" value="1"/>
+		<value name="MODE_WB_1_BLOCK" value="2"/>
+		<value name="MODE_WB_0_LINE" value="3"/>
+		<value name="MODE_WB_1_LINE" value="4"/>
+		<value name="MODE_WB_2_LINE" value="5"/>
 	</enum>
 
 	<enum name="mdp5_pack_3d">
@@ -110,30 +114,25 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 	</enum>
 
 	<bitset name="MDP5_IRQ">
-		<bitfield name="INTF0_WB_ROT_COMP"        pos="0"  type="boolean"/>
-		<bitfield name="INTF1_WB_ROT_COMP"        pos="1"  type="boolean"/>
-		<bitfield name="INTF2_WB_ROT_COMP"        pos="2"  type="boolean"/>
-		<bitfield name="INTF3_WB_ROT_COMP"        pos="3"  type="boolean"/>
-		<bitfield name="INTF0_WB_WFD"             pos="4"  type="boolean"/>
-		<bitfield name="INTF1_WB_WFD"             pos="5"  type="boolean"/>
-		<bitfield name="INTF2_WB_WFD"             pos="6"  type="boolean"/>
-		<bitfield name="INTF3_WB_WFD"             pos="7"  type="boolean"/>
-		<bitfield name="INTF0_PING_PONG_COMP"     pos="8"  type="boolean"/>
-		<bitfield name="INTF1_PING_PONG_COMP"     pos="9"  type="boolean"/>
-		<bitfield name="INTF2_PING_PONG_COMP"     pos="10" type="boolean"/>
-		<bitfield name="INTF3_PING_PONG_COMP"     pos="11" type="boolean"/>
-		<bitfield name="INTF0_PING_PONG_RD_PTR"   pos="12" type="boolean"/>
-		<bitfield name="INTF1_PING_PONG_RD_PTR"   pos="13" type="boolean"/>
-		<bitfield name="INTF2_PING_PONG_RD_PTR"   pos="14" type="boolean"/>
-		<bitfield name="INTF3_PING_PONG_RD_PTR"   pos="15" type="boolean"/>
-		<bitfield name="INTF0_PING_PONG_WR_PTR"   pos="16" type="boolean"/>
-		<bitfield name="INTF1_PING_PONG_WR_PTR"   pos="17" type="boolean"/>
-		<bitfield name="INTF2_PING_PONG_WR_PTR"   pos="18" type="boolean"/>
-		<bitfield name="INTF3_PING_PONG_WR_PTR"   pos="19" type="boolean"/>
-		<bitfield name="INTF0_PING_PONG_AUTO_REF" pos="20" type="boolean"/>
-		<bitfield name="INTF1_PING_PONG_AUTO_REF" pos="21" type="boolean"/>
-		<bitfield name="INTF2_PING_PONG_AUTO_REF" pos="22" type="boolean"/>
-		<bitfield name="INTF3_PING_PONG_AUTO_REF" pos="23" type="boolean"/>
+		<bitfield name="WB_0_DONE"                pos="0"  type="boolean"/>
+		<bitfield name="WB_1_DONE"                pos="1"  type="boolean"/>
+		<bitfield name="WB_2_DONE"                pos="4"  type="boolean"/>
+		<bitfield name="PING_PONG_0_DONE"         pos="8"  type="boolean"/>
+		<bitfield name="PING_PONG_1_DONE"         pos="9"  type="boolean"/>
+		<bitfield name="PING_PONG_2_DONE"         pos="10" type="boolean"/>
+		<bitfield name="PING_PONG_3_DONE"         pos="11" type="boolean"/>
+		<bitfield name="PING_PONG_0_RD_PTR"       pos="12" type="boolean"/>
+		<bitfield name="PING_PONG_1_RD_PTR"       pos="13" type="boolean"/>
+		<bitfield name="PING_PONG_2_RD_PTR"       pos="14" type="boolean"/>
+		<bitfield name="PING_PONG_3_RD_PTR"       pos="15" type="boolean"/>
+		<bitfield name="PING_PONG_0_WR_PTR"       pos="16" type="boolean"/>
+		<bitfield name="PING_PONG_1_WR_PTR"       pos="17" type="boolean"/>
+		<bitfield name="PING_PONG_2_WR_PTR"       pos="18" type="boolean"/>
+		<bitfield name="PING_PONG_3_WR_PTR"       pos="19" type="boolean"/>
+		<bitfield name="PING_PONG_0_AUTO_REF"     pos="20" type="boolean"/>
+		<bitfield name="PING_PONG_1_AUTO_REF"     pos="21" type="boolean"/>
+		<bitfield name="PING_PONG_2_AUTO_REF"     pos="22" type="boolean"/>
+		<bitfield name="PING_PONG_3_AUTO_REF"     pos="23" type="boolean"/>
 		<bitfield name="INTF0_UNDER_RUN"          pos="24" type="boolean"/>
 		<bitfield name="INTF0_VSYNC"              pos="25" type="boolean"/>
 		<bitfield name="INTF1_UNDER_RUN"          pos="26" type="boolean"/>
@@ -165,10 +164,10 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 	</reg32>
 
 	<reg32 offset="0x00104" name="DISP_INTF_SEL">
-		<bitfield name="INTF0" low="0"  high="7"  type="mdp5_intf"/>
-		<bitfield name="INTF1" low="8"  high="15" type="mdp5_intf"/>
-		<bitfield name="INTF2" low="16" high="23" type="mdp5_intf"/>
-		<bitfield name="INTF3" low="24" high="31" type="mdp5_intf"/>
+		<bitfield name="INTF0" low="0"  high="7"  type="mdp5_intf_type"/>
+		<bitfield name="INTF1" low="8"  high="15" type="mdp5_intf_type"/>
+		<bitfield name="INTF2" low="16" high="23" type="mdp5_intf_type"/>
+		<bitfield name="INTF3" low="24" high="31" type="mdp5_intf_type"/>
 	</reg32>
 	<reg32 offset="0x00110" name="INTR_EN" type="MDP5_IRQ"/>
 	<reg32 offset="0x00114" name="INTR_STATUS" type="MDP5_IRQ"/>
Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#3 lore raw

PATCH 2/4 drm/msm/mdp5: Enhance operation mode for pipeline configuration

In reply to Stephane Viau

DSI and WB interfaces need a more complex pipeline configuration than the current mdp5_ctl_set_intf().

For example, memory output connections need to be selected for WB. Interface mode (Video vs. Command modes) also need to be configured for DSI.

This change takes care of configuring the whole pipeline as far as operation mode goes. DSI and WB interfaces will be added later.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  2 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    | 39 ++-----------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 91 +++++++++++++++++++++++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  3 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 29 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     | 16 ++++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     | 48 ++++++++++++---
 7 files changed, 157 insertions(+), 71 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
index dba4d52..be587b8 100644
@@ -31,6 +31,8 @@ extern const struct mdp5_cfg_hw *mdp5_cfg;
 
 typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS);
 
+#define MDP5_INTF_IS_VIRTUAL_DISPLAY(intf_type)   ((intf_type) >= INTF_VIRTUAL)
+
 #define MDP5_SUB_BLOCK_DEFINITION \
 	int count; \
 	uint32_t base[MAX_BASES]
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +4 -35
index bfba236..15136f1 100644
@@ -611,48 +611,17 @@ void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file)
 }
 
 /* set interface for routing crtc->encoder: */
-void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
-		enum mdp5_intf intf_id)
+void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
-	uint32_t intf_sel;
-	unsigned long flags;
+	int lm = mdp5_crtc_get_lm(crtc);
 
 	/* now that we know what irq's we want: */
-	mdp5_crtc->err.irqmask = intf2err(intf);
-	mdp5_crtc->vblank.irqmask = intf2vblank(intf);
+	mdp5_crtc->err.irqmask = intf2err(intf->num);
+	mdp5_crtc->vblank.irqmask = intf2vblank(lm, intf);
 	mdp_irq_update(&mdp5_kms->base);
 
-	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
-	intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
-
-	switch (intf) {
-	case 0:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF0__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF0(intf_id);
-		break;
-	case 1:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF1__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF1(intf_id);
-		break;
-	case 2:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF2__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF2(intf_id);
-		break;
-	case 3:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF3__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF3(intf_id);
-		break;
-	default:
-		BUG();
-		break;
-	}
-
-	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel);
-	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
-
-	DBG("%s: intf_sel=%08x", mdp5_crtc->name, intf_sel);
 	mdp5_ctl_set_intf(mdp5_crtc->ctl, intf);
 }
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +81 -10

121 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +2 -1
index ad48788..271d5ac 100644
@@ -34,7 +34,8 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm);
  */
 struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc);
 
-int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf);
+struct mdp5_interface;
+int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, struct mdp5_interface *intf);
 
 int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable);
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +14 -15
index a09fa58..f3b6fe8 100644
@@ -23,8 +23,7 @@
 
 struct mdp5_encoder {
 	struct drm_encoder base;
-	int intf;
-	enum mdp5_intf intf_id;
+	struct mdp5_interface intf;
 	spinlock_t intf_lock;	/* protect REG_MDP5_INTF_* registers */
 	bool enabled;
 	uint32_t bsc;
@@ -126,7 +125,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
 	struct drm_device *dev = encoder->dev;
 	struct drm_connector *connector;
-	int intf = mdp5_encoder->intf;
+	int intf = mdp5_encoder->intf.num;
 	uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
 	uint32_t display_v_start, display_v_end;
 	uint32_t hsync_start_x, hsync_end_x;
@@ -188,7 +187,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
 	 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
 	 */
-	if (mdp5_encoder->intf_id == INTF_eDP) {
+	if (mdp5_encoder->intf.type == INTF_eDP) {
 		display_v_start += mode->htotal - mode->hsync_start;
 		display_v_end -= mode->hsync_start - mode->hdisplay;
 	}
@@ -224,14 +223,16 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
-	int intf = mdp5_encoder->intf;
+	int lm = mdp5_crtc_get_lm(encoder->crtc);
+	struct mdp5_interface *intf = &mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(!mdp5_encoder->enabled))
 		return;
 
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 
 	/*
@@ -242,7 +243,7 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 	 * the settings changes for the new modeset (like new
 	 * scanout buffer) don't latch properly..
 	 */
-	mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf));
+	mdp_irq_wait(&mdp5_kms->base, intf2vblank(lm, intf));
 
 	bs_set(mdp5_encoder, 0);
 
@@ -253,18 +254,17 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
-	int intf = mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(mdp5_encoder->enabled))
 		return;
 
-	mdp5_crtc_set_intf(encoder->crtc, mdp5_encoder->intf,
-			mdp5_encoder->intf_id);
+	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
 
 	bs_set(mdp5_encoder, 1);
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 
 	mdp5_encoder->enabled = true;
@@ -278,8 +278,8 @@ static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
 };
 
 /* initialize encoder */
-struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
-		enum mdp5_intf intf_id)
+struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
+				struct mdp5_interface *intf)
 {
 	struct drm_encoder *encoder = NULL;
 	struct mdp5_encoder *mdp5_encoder;
@@ -291,8 +291,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
 		goto fail;
 	}
 
-	mdp5_encoder->intf = intf;
-	mdp5_encoder->intf_id = intf_id;
+	memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf));
 	encoder = &mdp5_encoder->base;
 
 	spin_lock_init(&mdp5_encoder->intf_lock);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +14 -2
index 92b61db..390d9d2 100644
@@ -223,8 +223,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 	}
 
 	if (priv->hdmi) {
+		struct mdp5_interface intf = {
+				.num	= 3,
+				.type	= INTF_HDMI,
+				.mode	= MDP5_INTF_MODE_NONE,
+		};
+
 		/* Construct encoder for HDMI: */
-		encoder = mdp5_encoder_init(dev, 3, INTF_HDMI);
+		encoder = mdp5_encoder_init(dev, &intf);
 		if (IS_ERR(encoder)) {
 			dev_err(dev->dev, "failed to construct encoder\n");
 			ret = PTR_ERR(encoder);
@@ -242,8 +248,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 	}
 
 	if (priv->edp) {
+		struct mdp5_interface intf = {
+				.num	= 0,
+				.type	= INTF_eDP,
+				.mode	= MDP5_INTF_MODE_NONE,
+		};
+
 		/* Construct encoder for eDP: */
-		encoder = mdp5_encoder_init(dev, 0, INTF_eDP);
+		encoder = mdp5_encoder_init(dev, &intf);
 		if (IS_ERR(encoder)) {
 			dev_err(dev->dev, "failed to construct eDP encoder\n");
 			ret = PTR_ERR(encoder);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +40 -8

76 lines not on this page · raw message

Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#4 lore raw

Re: [PATCH 2/4] drm/msm/mdp5: Enhance operation mode for pipeline configuration

Hi,

Quoted 27 lines · Stephane Viau

DSI and WB interfaces need a more complex pipeline configuration than the current mdp5_ctl_set_intf().

For example, memory output connections need to be selected for WB. Interface mode (Video vs. Command modes) also need to be configured for DSI.

This change takes care of configuring the whole pipeline as far as operation mode goes. DSI and WB interfaces will be added later.

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  2 +
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    | 39 ++-----------
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 91 +++++++++++++++++++++++++----
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  3 +-
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 29 +++++----
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     | 16 ++++-
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     | 48 ++++++++++++---
  7 files changed, 157 insertions(+), 71 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +0 -0
index dba4d52..be587b8 100644

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h extern const struct mdp5_cfg_hw *mdp5_cfg; · line 35

Quoted 5 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
@@ -31,6 +31,8 @@ extern const struct mdp5_cfg_hw *mdp5_cfg;
 
  typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS);
 
+#define MDP5_INTF_IS_VIRTUAL_DISPLAY(intf_type)   ((intf_type) >= INTF_VIRTUAL)
+

Minor comment and probably matter of taste. Having the above as mdp5_intf_is_virtual() would seem better in the code.

<snip>

Thanks,
Archit
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#5 lore raw

PATCH 3/4 drm/msm/mdp5: Add START signal to kick off certain pipelines

In reply to Stephane Viau

Some interfaces (WB, DSI Command Mode) need to be kicked off through a START Signal. This signal needs to be sent at the right time and requests in some cases to keep track of the pipeline status (eg: whether pipeline registers are flushed AND output WB buffers are ready, in case of WB interface).

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |   2 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |   7 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  31 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 247 ++++++++++++++++++++++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  72 +++-----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  13 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |   1 +
 7 files changed, 276 insertions(+), 97 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +2 -0
index c078f30..72c075a 100644
@@ -31,6 +31,7 @@ const struct mdp5_cfg_hw msm8x74_config = {
 	.ctl = {
 		.count = 5,
 		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x0003ffff,
 	},
 	.pipe_vig = {
 		.count = 3,
@@ -78,6 +79,7 @@ const struct mdp5_cfg_hw apq8084_config = {
 	.ctl = {
 		.count = 5,
 		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x003fffff,
 	},
 	.pipe_vig = {
 		.count = 4,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +6 -1
index be587b8..be149b3 100644
@@ -46,6 +46,11 @@ struct mdp5_lm_block {
 	uint32_t nb_stages;		/* number of stages per blender */
 };
 
+struct mdp5_ctl_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	uint32_t flush_hw_mask;		/* FLUSH register's hardware mask */
+};
+
 struct mdp5_smp_block {
 	int mmb_count;			/* number of SMP MMBs */
 	int mmb_size;			/* MMB: size in bytes */
@@ -57,7 +62,7 @@ struct mdp5_cfg_hw {
 	char  *name;
 
 	struct mdp5_smp_block smp;
-	struct mdp5_sub_block ctl;
+	struct mdp5_ctl_block ctl;
 	struct mdp5_sub_block pipe_vig;
 	struct mdp5_sub_block pipe_rgb;
 	struct mdp5_sub_block pipe_dma;
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +18 -13
index 15136f1..9527ad1 100644
@@ -82,8 +82,6 @@ static void request_pending(struct drm_crtc *crtc, uint32_t pending)
 	mdp_irq_register(&get_kms(crtc)->base, &mdp5_crtc->vblank);
 }
 
-#define mdp5_lm_get_flush(lm)	mdp_ctl_flush_mask_lm(lm)
-
 static void crtc_flush(struct drm_crtc *crtc, u32 flush_mask)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
@@ -110,8 +108,8 @@ static void crtc_flush_all(struct drm_crtc *crtc)
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
 		flush_mask |= mdp5_plane_get_flush(plane);
 	}
-	flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
-	flush_mask |= mdp5_lm_get_flush(mdp5_crtc->lm);
+
+	flush_mask |= mdp_ctl_flush_mask_lm(mdp5_crtc->lm);
 
 	crtc_flush(crtc, flush_mask);
 }
@@ -442,13 +440,14 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
-	struct drm_gem_object *cursor_bo, *old_bo;
+	struct drm_gem_object *cursor_bo, *old_bo = NULL;
 	uint32_t blendcfg, cursor_addr, stride;
 	int ret, bpp, lm;
 	unsigned int depth;
 	enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
 	uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
 	uint32_t roi_w, roi_h;
+	bool cursor_enable = true;
 	unsigned long flags;
 
 	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
@@ -461,7 +460,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
 	if (!handle) {
 		DBG("Cursor off");
-		return mdp5_ctl_set_cursor(mdp5_crtc->ctl, false);
+		cursor_enable = false;
+		goto set_cursor;
 	}
 
 	cursor_bo = drm_gem_object_lookup(dev, file, handle);
@@ -502,11 +502,14 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
 	spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
 
-	ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true);
-	if (ret)
+set_cursor:
+	ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, 0, cursor_enable);
+	if (ret) {
+		dev_err(dev->dev, "failed to %sable cursor: %d\n",
+				cursor_enable ? "en" : "dis", ret);
 		goto end;
+	}
 
-	flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
 	crtc_flush(crtc, flush_mask);
 
 end:
@@ -628,11 +631,13 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf)
 int mdp5_crtc_get_lm(struct drm_crtc *crtc)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return WARN_ON(!crtc) ? -EINVAL : mdp5_crtc->lm;
+}
 
-	if (WARN_ON(!crtc))
-		return -EINVAL;
-
-	return mdp5_crtc->lm;
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return WARN_ON(!crtc) ? NULL : mdp5_crtc->ctl;
 }
 
 /* initialize crtc */
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +215 -32

355 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +23 -49

94 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +11 -2
index f3b6fe8..a17eb9c 100644
@@ -217,12 +217,15 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3);  /* frame+line? */
 
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+
+	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
 }
 
 static void mdp5_encoder_disable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc);
 	int lm = mdp5_crtc_get_lm(encoder->crtc);
 	struct mdp5_interface *intf = &mdp5_encoder->intf;
 	int intfn = mdp5_encoder->intf.num;
@@ -231,9 +234,12 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 	if (WARN_ON(!mdp5_encoder->enabled))
 		return;
 
+	mdp5_ctl_set_encoder_state(ctl, false);
+
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
 
 	/*
 	 * Wait for a vsync so we know the ENABLE=0 latched before
@@ -254,18 +260,21 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc);
+	struct mdp5_interface *intf = &mdp5_encoder->intf;
 	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(mdp5_encoder->enabled))
 		return;
 
-	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
-
 	bs_set(mdp5_encoder, 1);
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
+
+	mdp5_ctl_set_encoder_state(ctl, true);
 
 	mdp5_encoder->enabled = true;
 }
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +1 -0
index 1a6aa49..690edfd 100644
@@ -230,6 +230,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
 uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
 
 int mdp5_crtc_get_lm(struct drm_crtc *crtc);
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc);
 void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
 void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf);
 struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#6 lore raw

PATCH 4/4 drm/msm/mdp5: Make the intf connection in config module

In reply to Stephane Viau

Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |   8 +++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   4 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 111 ++++++++++++++++++--------------
 3 files changed, 74 insertions(+), 49 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 72c075a..8bee023 100644
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
 		.count = 4,
 		.base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
 	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
 	.max_clk = 200000000,
 };
 
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = {
 		.count = 5,
 		.base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
 	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
 	.max_clk = 320000000,
 };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +4 -0
index be149b3..4e91f14 100644
@@ -58,6 +58,8 @@ struct mdp5_smp_block {
 	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
 };
 
+#define MDP5_INTF_NUM_MAX	5
+
 struct mdp5_cfg_hw {
 	char  *name;
 
@@ -71,6 +73,8 @@ struct mdp5_cfg_hw {
 	struct mdp5_sub_block ad;
 	struct mdp5_sub_block intf;
 
+	u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+
 	uint32_t max_clk;
 };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +62 -49

139 lines not on this page · raw message

Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#7 lore raw

Re: [PATCH 4/4] drm/msm/mdp5: Make the intf connection in config module

Hi,

Quoted 51 lines · Stephane Viau

Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another.

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |   8 +++
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   4 ++
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 111 ++++++++++++++++++--------------
  3 files changed, 74 insertions(+), 49 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 72c075a..8bee023 100644
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
  		.count = 4,
  		.base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
  	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
  	.max_clk = 200000000,
  };
 
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = {
  		.count = 5,
  		.base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
  	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
  	.max_clk = 320000000,
  };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
index be149b3..4e91f14 100644
@@ -58,6 +58,8 @@ struct mdp5_smp_block {
  	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
  };
 
+#define MDP5_INTF_NUM_MAX	5
+
  struct mdp5_cfg_hw {
  	char  *name;
 

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h struct mdp5_cfg_hw { · line 77

Quoted 5 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
@@ -71,6 +73,8 @@ struct mdp5_cfg_hw {
  	struct mdp5_sub_block ad;
  	struct mdp5_sub_block intf;
 
+	u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+

The array type could be "enum mdp5_intf_type" rather than u32.

Quoted 138 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +0 -0
  	uint32_t max_clk;
  };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +58 -48
index 390d9d2..8cec00e 100644
@@ -161,6 +161,44 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
  	return 0;
  }
 
+static int construct_encoder(struct mdp5_kms *mdp5_kms,
+		enum mdp5_intf_type intf_type, int intf_num)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct mdp5_interface intf = {
+			.num	= intf_num,
+			.type	= intf_type,
+			.mode	= MDP5_INTF_MODE_NONE,
+	};
+	int ret = 0;
+
+	encoder = mdp5_encoder_init(dev, &intf);
+	if (IS_ERR(encoder)) {
+		ret = PTR_ERR(encoder);
+		dev_err(dev->dev, "failed to construct encoder: %d\n", ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
+	priv->encoders[priv->num_encoders++] = encoder;
+
+	if (intf_type == INTF_HDMI) {
+		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
+		if (ret)
+			dev_err(dev->dev, "failed to init HDMI: %d\n", ret);
+
+	} else if (intf_type == INTF_eDP) {
+		/* Construct bridge/connector for eDP: */
+		ret = msm_edp_modeset_init(priv->edp, dev, encoder);
+		if (ret)
+			dev_err(dev->dev, "failed to init eDP: %d\n", ret);
+	}
+
+	return ret;
+}
+
  static int modeset_init(struct mdp5_kms *mdp5_kms)
  {
  	static const enum mdp5_pipe crtcs[] = {
@@ -171,7 +209,6 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
  	};
  	struct drm_device *dev = mdp5_kms->dev;
  	struct msm_drm_private *priv = dev->dev_private;
-	struct drm_encoder *encoder;
  	const struct mdp5_cfg_hw *hw_cfg;
  	int i, ret;
 
@@ -222,56 +259,29 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
  		}
  	}
 
-	if (priv->hdmi) {
-		struct mdp5_interface intf = {
-				.num	= 3,
-				.type	= INTF_HDMI,
-				.mode	= MDP5_INTF_MODE_NONE,
-		};
-
-		/* Construct encoder for HDMI: */
-		encoder = mdp5_encoder_init(dev, &intf);
-		if (IS_ERR(encoder)) {
-			dev_err(dev->dev, "failed to construct encoder\n");
-			ret = PTR_ERR(encoder);
-			goto fail;
-		}
-
-		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
-		priv->encoders[priv->num_encoders++] = encoder;
-
-		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
-		if (ret) {
-			dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
-			goto fail;
-		}
-	}
-
-	if (priv->edp) {
-		struct mdp5_interface intf = {
-				.num	= 0,
-				.type	= INTF_eDP,
-				.mode	= MDP5_INTF_MODE_NONE,
-		};
-
-		/* Construct encoder for eDP: */
-		encoder = mdp5_encoder_init(dev, &intf);
-		if (IS_ERR(encoder)) {
-			dev_err(dev->dev, "failed to construct eDP encoder\n");
-			ret = PTR_ERR(encoder);
-			goto fail;
+	/* Construct external display interfaces' encoders: */
+	for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) {
+		enum mdp5_intf_type intf_type = hw_cfg->intfs[i];
+
+		switch (intf_type) {
+		case INTF_DISABLED:
+			break;
+		case INTF_eDP:
+			if (priv->edp)
+				ret = construct_encoder(mdp5_kms, INTF_eDP, i);
+			break;
+		case INTF_HDMI:
+			if (priv->hdmi)
+				ret = construct_encoder(mdp5_kms, INTF_HDMI, i);
+			break;
+		default:
+			dev_err(dev->dev, "unknown intf: %d\n", intf_type);
+			ret = -EINVAL;
+			break;
  		}
 
-		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
-		priv->encoders[priv->num_encoders++] = encoder;
-
-		/* Construct bridge/connector for eDP: */
-		ret = msm_edp_modeset_init(priv->edp, dev, encoder);
-		if (ret) {
-			dev_err(dev->dev, "failed to initialize eDP: %d\n",
-									ret);
+		if (ret)
  			goto fail;
-		}
  	}
 
  	return 0;

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device *dev) · line 430

Quoted 7 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +3 -1
@@ -415,8 +425,11 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
  	 * we don't disable):
  	 */
  	mdp5_enable(mdp5_kms);
-	for (i = 0; i < config->hw->intf.count; i++)
+	for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
+		if (MDP5_INTF_IS_VIRTUAL_DISPLAY(config->hw->intfs[i]))
+			continue;

This may not be sufficient to prevent register writes to interfaces that don't exist. We'd probably need:

	if(MDP5_INTF_IS_VIRTUAL_DISPLAY(config->hw->intfs[i]) ||
			config->hw->intfs[i] == INTF_DISABLED)
		continue;

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device *dev) · line 432

Quoted 2 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +1 -0
  		mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
+	}

Writing to registers for a non existent interface shouldn't do any harm, but it's best to be safe :)

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device *dev) · line 435

Quoted 4 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +0 -0
  	mdp5_disable(mdp5_kms);
  	mdelay(16);
 

Thanks,
Archit

Signature · 6 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#8 lore raw

Re: [PATCH 4/4] drm/msm/mdp5: Make the intf connection in config module

Quoted 1 line

Hi,

Hi Archit,

Quoted 55 lines · Stephane Viau
Quoted 53 lines

Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another.

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |   8 +++
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   4 ++
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 111
++++++++++++++++++--------------
  3 files changed, 74 insertions(+), 49 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 72c075a..8bee023 100644
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
  		.count = 4,
  		.base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
  	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
  	.max_clk = 200000000,
  };
 
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = {
  		.count = 5,
  		.base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
  	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
  	.max_clk = 320000000,
  };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
index be149b3..4e91f14 100644
@@ -58,6 +58,8 @@ struct mdp5_smp_block {
  	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
  };
 
+#define MDP5_INTF_NUM_MAX	5
+
  struct mdp5_cfg_hw {
  	char  *name;
 
Quoted 9 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h struct mdp5_cfg_hw { · line 77

Quoted 6 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
@@ -71,6 +73,8 @@ struct mdp5_cfg_hw {
  	struct mdp5_sub_block ad;
  	struct mdp5_sub_block intf;
 
+	u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+

The array type could be "enum mdp5_intf_type" rather than u32.

The problem here is that mdp5_cfg.h must be included before mdp5.xml.h (see mdp5_kms.h #24) so that mdp5_cfg pointer can be resolved in the latter.
mdp5_cfg.h hence cannot use any types defined in mdp5.xml.h, including 'enum mdp5_intf_type'.

Quoted 151 lines
Quoted 139 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +0 -0
  	uint32_t max_clk;
  };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +58 -48
index 390d9d2..8cec00e 100644
@@ -161,6 +161,44 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
  	return 0;
  }
 
+static int construct_encoder(struct mdp5_kms *mdp5_kms,
+		enum mdp5_intf_type intf_type, int intf_num)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct mdp5_interface intf = {
+			.num	= intf_num,
+			.type	= intf_type,
+			.mode	= MDP5_INTF_MODE_NONE,
+	};
+	int ret = 0;
+
+	encoder = mdp5_encoder_init(dev, &intf);
+	if (IS_ERR(encoder)) {
+		ret = PTR_ERR(encoder);
+		dev_err(dev->dev, "failed to construct encoder: %d\n", ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
+	priv->encoders[priv->num_encoders++] = encoder;
+
+	if (intf_type == INTF_HDMI) {
+		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
+		if (ret)
+			dev_err(dev->dev, "failed to init HDMI: %d\n", ret);
+
+	} else if (intf_type == INTF_eDP) {
+		/* Construct bridge/connector for eDP: */
+		ret = msm_edp_modeset_init(priv->edp, dev, encoder);
+		if (ret)
+			dev_err(dev->dev, "failed to init eDP: %d\n", ret);
+	}
+
+	return ret;
+}
+
  static int modeset_init(struct mdp5_kms *mdp5_kms)
  {
  	static const enum mdp5_pipe crtcs[] = {
@@ -171,7 +209,6 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
  	};
  	struct drm_device *dev = mdp5_kms->dev;
  	struct msm_drm_private *priv = dev->dev_private;
-	struct drm_encoder *encoder;
  	const struct mdp5_cfg_hw *hw_cfg;
  	int i, ret;
 
@@ -222,56 +259,29 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
  		}
  	}
 
-	if (priv->hdmi) {
-		struct mdp5_interface intf = {
-				.num	= 3,
-				.type	= INTF_HDMI,
-				.mode	= MDP5_INTF_MODE_NONE,
-		};
-
-		/* Construct encoder for HDMI: */
-		encoder = mdp5_encoder_init(dev, &intf);
-		if (IS_ERR(encoder)) {
-			dev_err(dev->dev, "failed to construct encoder\n");
-			ret = PTR_ERR(encoder);
-			goto fail;
-		}
-
-		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
-		priv->encoders[priv->num_encoders++] = encoder;
-
-		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
-		if (ret) {
-			dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
-			goto fail;
-		}
-	}
-
-	if (priv->edp) {
-		struct mdp5_interface intf = {
-				.num	= 0,
-				.type	= INTF_eDP,
-				.mode	= MDP5_INTF_MODE_NONE,
-		};
-
-		/* Construct encoder for eDP: */
-		encoder = mdp5_encoder_init(dev, &intf);
-		if (IS_ERR(encoder)) {
-			dev_err(dev->dev, "failed to construct eDP encoder\n");
-			ret = PTR_ERR(encoder);
-			goto fail;
+	/* Construct external display interfaces' encoders: */
+	for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) {
+		enum mdp5_intf_type intf_type = hw_cfg->intfs[i];
+
+		switch (intf_type) {
+		case INTF_DISABLED:
+			break;
+		case INTF_eDP:
+			if (priv->edp)
+				ret = construct_encoder(mdp5_kms, INTF_eDP, i);
+			break;
+		case INTF_HDMI:
+			if (priv->hdmi)
+				ret = construct_encoder(mdp5_kms, INTF_HDMI, i);
+			break;
+		default:
+			dev_err(dev->dev, "unknown intf: %d\n", intf_type);
+			ret = -EINVAL;
+			break;
  		}
 
-		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
-		priv->encoders[priv->num_encoders++] = encoder;
-
-		/* Construct bridge/connector for eDP: */
-		ret = msm_edp_modeset_init(priv->edp, dev, encoder);
-		if (ret) {
-			dev_err(dev->dev, "failed to initialize eDP: %d\n",
-									ret);
+		if (ret)
  			goto fail;
-		}
  	}
 
  	return 0;

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device · line 431

Quoted 8 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +3 -1
@@ -415,8 +425,11 @@ struct msm_kms *mdp5_kms_init(struct drm_device
 *dev)
  	 * we don't disable):
  	 */
  	mdp5_enable(mdp5_kms);
-	for (i = 0; i < config->hw->intf.count; i++)
+	for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
+		if (MDP5_INTF_IS_VIRTUAL_DISPLAY(config->hw->intfs[i]))
+			continue;

This may not be sufficient to prevent register writes to interfaces that don't exist. We'd probably need:

Quoted 4 lines
	if(MDP5_INTF_IS_VIRTUAL_DISPLAY(config->hw->intfs[i]) ||
			config->hw->intfs[i] == INTF_DISABLED)
		continue;

We actually need to disable all display interfaces even though they are not listed as "enabled". If we do not do so, we get faults[1]. As you mentioned, it shouldn't harm to write 0 in non existent interfaces' registers.

[1] http://www.hastebin.com/raw/dekaqaboju

Quoted 14 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device *dev) · line 432

Quoted 2 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +1 -0
  		mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
+	}

Writing to registers for a non existent interface shouldn't do any harm, but it's best to be safe :)

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device *dev) · line 434

Quoted 4 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +0 -0
  	mdp5_disable(mdp5_kms);
  	mdelay(16);

Thanks,
Archit

Quoted 9 lines

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Thanks,
Stéphane.

Signature · 9 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#9 lore raw

Re: [PATCH 4/4] drm/msm/mdp5: Make the intf connection in config module

Quoted 69 lines · Stéphane Viau
Quoted 1 line

Hi,

Hi Archit,

Quoted 55 lines · Stephane Viau
Quoted 53 lines

Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another.

---
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |   8 +++
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   4 ++
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 111
++++++++++++++++++--------------
   3 files changed, 74 insertions(+), 49 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 72c075a..8bee023 100644
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
   		.count = 4,
   		.base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
   	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
   	.max_clk = 200000000,
   };
 
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = {
   		.count = 5,
   		.base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
   	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
   	.max_clk = 320000000,
   };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
index be149b3..4e91f14 100644
@@ -58,6 +58,8 @@ struct mdp5_smp_block {
   	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
   };
 
+#define MDP5_INTF_NUM_MAX	5
+
   struct mdp5_cfg_hw {
   	char  *name;
 
Quoted 9 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h struct mdp5_cfg_hw { · line 77

Quoted 6 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +2 -0
@@ -71,6 +73,8 @@ struct mdp5_cfg_hw {
   	struct mdp5_sub_block ad;
   	struct mdp5_sub_block intf;
 
+	u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+

The array type could be "enum mdp5_intf_type" rather than u32.

Quoted 5 lines

The problem here is that mdp5_cfg.h must be included before mdp5.xml.h (see mdp5_kms.h #24) so that mdp5_cfg pointer can be resolved in the latter.
mdp5_cfg.h hence cannot use any types defined in mdp5.xml.h, including 'enum mdp5_intf_type'.

Ah okay.

Quoted 157 lines
Quoted 152 lines
Quoted 140 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +0 -0
   	uint32_t max_clk;
   };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +58 -48
index 390d9d2..8cec00e 100644
@@ -161,6 +161,44 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
   	return 0;
   }
 
+static int construct_encoder(struct mdp5_kms *mdp5_kms,
+		enum mdp5_intf_type intf_type, int intf_num)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct mdp5_interface intf = {
+			.num	= intf_num,
+			.type	= intf_type,
+			.mode	= MDP5_INTF_MODE_NONE,
+	};
+	int ret = 0;
+
+	encoder = mdp5_encoder_init(dev, &intf);
+	if (IS_ERR(encoder)) {
+		ret = PTR_ERR(encoder);
+		dev_err(dev->dev, "failed to construct encoder: %d\n", ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
+	priv->encoders[priv->num_encoders++] = encoder;
+
+	if (intf_type == INTF_HDMI) {
+		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
+		if (ret)
+			dev_err(dev->dev, "failed to init HDMI: %d\n", ret);
+
+	} else if (intf_type == INTF_eDP) {
+		/* Construct bridge/connector for eDP: */
+		ret = msm_edp_modeset_init(priv->edp, dev, encoder);
+		if (ret)
+			dev_err(dev->dev, "failed to init eDP: %d\n", ret);
+	}
+
+	return ret;
+}
+
   static int modeset_init(struct mdp5_kms *mdp5_kms)
   {
   	static const enum mdp5_pipe crtcs[] = {
@@ -171,7 +209,6 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
   	};
   	struct drm_device *dev = mdp5_kms->dev;
   	struct msm_drm_private *priv = dev->dev_private;
-	struct drm_encoder *encoder;
   	const struct mdp5_cfg_hw *hw_cfg;
   	int i, ret;
 
@@ -222,56 +259,29 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
   		}
   	}
 
-	if (priv->hdmi) {
-		struct mdp5_interface intf = {
-				.num	= 3,
-				.type	= INTF_HDMI,
-				.mode	= MDP5_INTF_MODE_NONE,
-		};
-
-		/* Construct encoder for HDMI: */
-		encoder = mdp5_encoder_init(dev, &intf);
-		if (IS_ERR(encoder)) {
-			dev_err(dev->dev, "failed to construct encoder\n");
-			ret = PTR_ERR(encoder);
-			goto fail;
-		}
-
-		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
-		priv->encoders[priv->num_encoders++] = encoder;
-
-		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
-		if (ret) {
-			dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
-			goto fail;
-		}
-	}
-
-	if (priv->edp) {
-		struct mdp5_interface intf = {
-				.num	= 0,
-				.type	= INTF_eDP,
-				.mode	= MDP5_INTF_MODE_NONE,
-		};
-
-		/* Construct encoder for eDP: */
-		encoder = mdp5_encoder_init(dev, &intf);
-		if (IS_ERR(encoder)) {
-			dev_err(dev->dev, "failed to construct eDP encoder\n");
-			ret = PTR_ERR(encoder);
-			goto fail;
+	/* Construct external display interfaces' encoders: */
+	for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) {
+		enum mdp5_intf_type intf_type = hw_cfg->intfs[i];
+
+		switch (intf_type) {
+		case INTF_DISABLED:
+			break;
+		case INTF_eDP:
+			if (priv->edp)
+				ret = construct_encoder(mdp5_kms, INTF_eDP, i);
+			break;
+		case INTF_HDMI:
+			if (priv->hdmi)
+				ret = construct_encoder(mdp5_kms, INTF_HDMI, i);
+			break;
+		default:
+			dev_err(dev->dev, "unknown intf: %d\n", intf_type);
+			ret = -EINVAL;
+			break;
   		}
 
-		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
-		priv->encoders[priv->num_encoders++] = encoder;
-
-		/* Construct bridge/connector for eDP: */
-		ret = msm_edp_modeset_init(priv->edp, dev, encoder);
-		if (ret) {
-			dev_err(dev->dev, "failed to initialize eDP: %d\n",
-									ret);
+		if (ret)
   			goto fail;
-		}
   	}
 
   	return 0;

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c struct msm_kms *mdp5_kms_init(struct drm_device · line 431

Quoted 8 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +3 -1
@@ -415,8 +425,11 @@ struct msm_kms *mdp5_kms_init(struct drm_device
 *dev)
   	 * we don't disable):
   	 */
   	mdp5_enable(mdp5_kms);
-	for (i = 0; i < config->hw->intf.count; i++)
+	for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
+		if (MDP5_INTF_IS_VIRTUAL_DISPLAY(config->hw->intfs[i]))
+			continue;

This may not be sufficient to prevent register writes to interfaces that don't exist. We'd probably need:

Quoted 4 lines
	if(MDP5_INTF_IS_VIRTUAL_DISPLAY(config->hw->intfs[i]) ||
			config->hw->intfs[i] == INTF_DISABLED)
		continue;
Quoted 6 lines

We actually need to disable all display interfaces even though they are not listed as "enabled". If we do not do so, we get faults[1]. As you mentioned, it shouldn't harm to write 0 in non existent interfaces' registers.

[1] http://www.hastebin.com/raw/dekaqaboju

Thanks for the clarification.

Archit

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#10 lore raw

v2 cover drm/msm: preparation for WB/DSI connectors

In reply to Stephane Viau

WB and DSI support are in the pipe and will come out soon. Before that, we need to prepare the MDP5 driver so we can support these connectors.

v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]

Stephane Viau (4):
drm/msm/mdp5: Update generated header files drm/msm/mdp5: Enhance operation mode for pipeline configuration drm/msm/mdp5: Add START signal to kick off certain pipelines drm/msm/mdp5: Make the intf connection in config module

 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h     |  68 +++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |  10 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  15 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  70 ++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 326 +++++++++++++++++++++++++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  75 +++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  40 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     |  99 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |  49 ++++-
 9 files changed, 521 insertions(+), 231 deletions(-)
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#11 lore raw

PATCH v2 1/4 drm/msm/mdp5: Update generated header files

Prepare for pipeline operation mode configuration, in particular for DSI and WB modes.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 68 ++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 35 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +33 -35
index c276624..095a54c 100644
@@ -8,7 +8,7 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27229 bytes, from 2015-02-10 17:00:41)
+- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27094 bytes, from 2015-01-23 16:27:31)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2014-06-02 18:31:15)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml      (   2357 bytes, from 2015-01-23 16:20:19)
 
@@ -37,11 +37,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 
-enum mdp5_intf {
+enum mdp5_intf_type {
+	INTF_DISABLED = 0,
 	INTF_DSI = 1,
 	INTF_HDMI = 3,
 	INTF_LCDC = 5,
 	INTF_eDP = 9,
+	INTF_VIRTUAL = 100,
+	INTF_WB = 101,
 };
 
 enum mdp5_intfnum {
@@ -67,11 +70,11 @@ enum mdp5_pipe {
 
 enum mdp5_ctl_mode {
 	MODE_NONE = 0,
-	MODE_ROT0 = 1,
-	MODE_ROT1 = 2,
-	MODE_WB0 = 3,
-	MODE_WB1 = 4,
-	MODE_WFD = 5,
+	MODE_WB_0_BLOCK = 1,
+	MODE_WB_1_BLOCK = 2,
+	MODE_WB_0_LINE = 3,
+	MODE_WB_1_LINE = 4,
+	MODE_WB_2_LINE = 5,
 };
 
 enum mdp5_pack_3d {
@@ -144,30 +147,25 @@ enum mdp5_data_format {
 	DATA_FORMAT_YUV = 1,
 };
 
-#define MDP5_IRQ_INTF0_WB_ROT_COMP				0x00000001
-#define MDP5_IRQ_INTF1_WB_ROT_COMP				0x00000002
-#define MDP5_IRQ_INTF2_WB_ROT_COMP				0x00000004
-#define MDP5_IRQ_INTF3_WB_ROT_COMP				0x00000008
-#define MDP5_IRQ_INTF0_WB_WFD					0x00000010
-#define MDP5_IRQ_INTF1_WB_WFD					0x00000020
-#define MDP5_IRQ_INTF2_WB_WFD					0x00000040
-#define MDP5_IRQ_INTF3_WB_WFD					0x00000080
-#define MDP5_IRQ_INTF0_PING_PONG_COMP				0x00000100
-#define MDP5_IRQ_INTF1_PING_PONG_COMP				0x00000200
-#define MDP5_IRQ_INTF2_PING_PONG_COMP				0x00000400
-#define MDP5_IRQ_INTF3_PING_PONG_COMP				0x00000800
-#define MDP5_IRQ_INTF0_PING_PONG_RD_PTR				0x00001000
-#define MDP5_IRQ_INTF1_PING_PONG_RD_PTR				0x00002000
-#define MDP5_IRQ_INTF2_PING_PONG_RD_PTR				0x00004000
-#define MDP5_IRQ_INTF3_PING_PONG_RD_PTR				0x00008000
-#define MDP5_IRQ_INTF0_PING_PONG_WR_PTR				0x00010000
-#define MDP5_IRQ_INTF1_PING_PONG_WR_PTR				0x00020000
-#define MDP5_IRQ_INTF2_PING_PONG_WR_PTR				0x00040000
-#define MDP5_IRQ_INTF3_PING_PONG_WR_PTR				0x00080000
-#define MDP5_IRQ_INTF0_PING_PONG_AUTO_REF			0x00100000
-#define MDP5_IRQ_INTF1_PING_PONG_AUTO_REF			0x00200000
-#define MDP5_IRQ_INTF2_PING_PONG_AUTO_REF			0x00400000
-#define MDP5_IRQ_INTF3_PING_PONG_AUTO_REF			0x00800000
+#define MDP5_IRQ_WB_0_DONE					0x00000001
+#define MDP5_IRQ_WB_1_DONE					0x00000002
+#define MDP5_IRQ_WB_2_DONE					0x00000010
+#define MDP5_IRQ_PING_PONG_0_DONE				0x00000100
+#define MDP5_IRQ_PING_PONG_1_DONE				0x00000200
+#define MDP5_IRQ_PING_PONG_2_DONE				0x00000400
+#define MDP5_IRQ_PING_PONG_3_DONE				0x00000800
+#define MDP5_IRQ_PING_PONG_0_RD_PTR				0x00001000
+#define MDP5_IRQ_PING_PONG_1_RD_PTR				0x00002000
+#define MDP5_IRQ_PING_PONG_2_RD_PTR				0x00004000
+#define MDP5_IRQ_PING_PONG_3_RD_PTR				0x00008000
+#define MDP5_IRQ_PING_PONG_0_WR_PTR				0x00010000
+#define MDP5_IRQ_PING_PONG_1_WR_PTR				0x00020000
+#define MDP5_IRQ_PING_PONG_2_WR_PTR				0x00040000
+#define MDP5_IRQ_PING_PONG_3_WR_PTR				0x00080000
+#define MDP5_IRQ_PING_PONG_0_AUTO_REF				0x00100000
+#define MDP5_IRQ_PING_PONG_1_AUTO_REF				0x00200000
+#define MDP5_IRQ_PING_PONG_2_AUTO_REF				0x00400000
+#define MDP5_IRQ_PING_PONG_3_AUTO_REF				0x00800000
 #define MDP5_IRQ_INTF0_UNDER_RUN				0x01000000
 #define MDP5_IRQ_INTF0_VSYNC					0x02000000
 #define MDP5_IRQ_INTF1_UNDER_RUN				0x04000000
@@ -202,25 +200,25 @@ static inline uint32_t MDP5_MDP_VERSION_MAJOR(uint32_t val)
 #define REG_MDP5_DISP_INTF_SEL					0x00000104
 #define MDP5_DISP_INTF_SEL_INTF0__MASK				0x000000ff
 #define MDP5_DISP_INTF_SEL_INTF0__SHIFT				0
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF0__SHIFT) & MDP5_DISP_INTF_SEL_INTF0__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF1__MASK				0x0000ff00
 #define MDP5_DISP_INTF_SEL_INTF1__SHIFT				8
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF1__SHIFT) & MDP5_DISP_INTF_SEL_INTF1__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF2__MASK				0x00ff0000
 #define MDP5_DISP_INTF_SEL_INTF2__SHIFT				16
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF2__SHIFT) & MDP5_DISP_INTF_SEL_INTF2__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF3__MASK				0xff000000
 #define MDP5_DISP_INTF_SEL_INTF3__SHIFT				24
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF3__SHIFT) & MDP5_DISP_INTF_SEL_INTF3__MASK;
 }
Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#12 lore raw

PATCH v2 2/4 drm/msm/mdp5: Enhance operation mode for pipeline configuration

In reply to Stephane Viau

DSI and WB interfaces need a more complex pipeline configuration than the current mdp5_ctl_set_intf().

For example, memory output connections need to be selected for WB. Interface mode (Video vs. Command modes) also need to be configured for DSI.

This change takes care of configuring the whole pipeline as far as operation mode goes. DSI and WB interfaces will be added later.

v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  4 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    | 39 ++-----------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 91 +++++++++++++++++++++++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  3 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 29 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     | 16 ++++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     | 48 ++++++++++++---
 7 files changed, 159 insertions(+), 71 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +4 -0
index dba4d52..4e90740 100644
@@ -84,6 +84,10 @@ const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_hn
 struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_hnd);
 int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_hnd);
 
+#define mdp5_cfg_intf_is_virtual(intf_type) ({	\
+	typeof(intf_type) __val = (intf_type);	\
+	(__val) >= INTF_VIRTUAL ? true : false; })
+
 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
 		uint32_t major, uint32_t minor);
 void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_hnd);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +4 -35
index bfba236..15136f1 100644
@@ -611,48 +611,17 @@ void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file)
 }
 
 /* set interface for routing crtc->encoder: */
-void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
-		enum mdp5_intf intf_id)
+void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
-	uint32_t intf_sel;
-	unsigned long flags;
+	int lm = mdp5_crtc_get_lm(crtc);
 
 	/* now that we know what irq's we want: */
-	mdp5_crtc->err.irqmask = intf2err(intf);
-	mdp5_crtc->vblank.irqmask = intf2vblank(intf);
+	mdp5_crtc->err.irqmask = intf2err(intf->num);
+	mdp5_crtc->vblank.irqmask = intf2vblank(lm, intf);
 	mdp_irq_update(&mdp5_kms->base);
 
-	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
-	intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
-
-	switch (intf) {
-	case 0:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF0__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF0(intf_id);
-		break;
-	case 1:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF1__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF1(intf_id);
-		break;
-	case 2:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF2__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF2(intf_id);
-		break;
-	case 3:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF3__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF3(intf_id);
-		break;
-	default:
-		BUG();
-		break;
-	}
-
-	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel);
-	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
-
-	DBG("%s: intf_sel=%08x", mdp5_crtc->name, intf_sel);
 	mdp5_ctl_set_intf(mdp5_crtc->ctl, intf);
 }
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +81 -10

121 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +2 -1
index ad48788..271d5ac 100644
@@ -34,7 +34,8 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm);
  */
 struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc);
 
-int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf);
+struct mdp5_interface;
+int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, struct mdp5_interface *intf);
 
 int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable);
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +14 -15
index a09fa58..f3b6fe8 100644
@@ -23,8 +23,7 @@
 
 struct mdp5_encoder {
 	struct drm_encoder base;
-	int intf;
-	enum mdp5_intf intf_id;
+	struct mdp5_interface intf;
 	spinlock_t intf_lock;	/* protect REG_MDP5_INTF_* registers */
 	bool enabled;
 	uint32_t bsc;
@@ -126,7 +125,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
 	struct drm_device *dev = encoder->dev;
 	struct drm_connector *connector;
-	int intf = mdp5_encoder->intf;
+	int intf = mdp5_encoder->intf.num;
 	uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
 	uint32_t display_v_start, display_v_end;
 	uint32_t hsync_start_x, hsync_end_x;
@@ -188,7 +187,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
 	 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
 	 */
-	if (mdp5_encoder->intf_id == INTF_eDP) {
+	if (mdp5_encoder->intf.type == INTF_eDP) {
 		display_v_start += mode->htotal - mode->hsync_start;
 		display_v_end -= mode->hsync_start - mode->hdisplay;
 	}
@@ -224,14 +223,16 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
-	int intf = mdp5_encoder->intf;
+	int lm = mdp5_crtc_get_lm(encoder->crtc);
+	struct mdp5_interface *intf = &mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(!mdp5_encoder->enabled))
 		return;
 
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 
 	/*
@@ -242,7 +243,7 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 	 * the settings changes for the new modeset (like new
 	 * scanout buffer) don't latch properly..
 	 */
-	mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf));
+	mdp_irq_wait(&mdp5_kms->base, intf2vblank(lm, intf));
 
 	bs_set(mdp5_encoder, 0);
 
@@ -253,18 +254,17 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
-	int intf = mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(mdp5_encoder->enabled))
 		return;
 
-	mdp5_crtc_set_intf(encoder->crtc, mdp5_encoder->intf,
-			mdp5_encoder->intf_id);
+	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
 
 	bs_set(mdp5_encoder, 1);
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 
 	mdp5_encoder->enabled = true;
@@ -278,8 +278,8 @@ static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
 };
 
 /* initialize encoder */
-struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
-		enum mdp5_intf intf_id)
+struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
+				struct mdp5_interface *intf)
 {
 	struct drm_encoder *encoder = NULL;
 	struct mdp5_encoder *mdp5_encoder;
@@ -291,8 +291,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
 		goto fail;
 	}
 
-	mdp5_encoder->intf = intf;
-	mdp5_encoder->intf_id = intf_id;
+	memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf));
 	encoder = &mdp5_encoder->base;
 
 	spin_lock_init(&mdp5_encoder->intf_lock);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +14 -2
index 92b61db..390d9d2 100644
@@ -223,8 +223,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 	}
 
 	if (priv->hdmi) {
+		struct mdp5_interface intf = {
+				.num	= 3,
+				.type	= INTF_HDMI,
+				.mode	= MDP5_INTF_MODE_NONE,
+		};
+
 		/* Construct encoder for HDMI: */
-		encoder = mdp5_encoder_init(dev, 3, INTF_HDMI);
+		encoder = mdp5_encoder_init(dev, &intf);
 		if (IS_ERR(encoder)) {
 			dev_err(dev->dev, "failed to construct encoder\n");
 			ret = PTR_ERR(encoder);
@@ -242,8 +248,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 	}
 
 	if (priv->edp) {
+		struct mdp5_interface intf = {
+				.num	= 0,
+				.type	= INTF_eDP,
+				.mode	= MDP5_INTF_MODE_NONE,
+		};
+
 		/* Construct encoder for eDP: */
-		encoder = mdp5_encoder_init(dev, 0, INTF_eDP);
+		encoder = mdp5_encoder_init(dev, &intf);
 		if (IS_ERR(encoder)) {
 			dev_err(dev->dev, "failed to construct eDP encoder\n");
 			ret = PTR_ERR(encoder);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +40 -8

76 lines not on this page · raw message

Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#13 lore raw

PATCH v2 3/4 drm/msm/mdp5: Add START signal to kick off certain pipelines

In reply to Stephane Viau

Some interfaces (WB, DSI Command Mode) need to be kicked off through a START Signal. This signal needs to be sent at the right time and requests in some cases to keep track of the pipeline status (eg: whether pipeline registers are flushed AND output WB buffers are ready, in case of WB interface).

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |   2 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |   7 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  31 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 247 ++++++++++++++++++++++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  72 +++-----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  13 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |   1 +
 7 files changed, 276 insertions(+), 97 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +2 -0
index c078f30..72c075a 100644
@@ -31,6 +31,7 @@ const struct mdp5_cfg_hw msm8x74_config = {
 	.ctl = {
 		.count = 5,
 		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x0003ffff,
 	},
 	.pipe_vig = {
 		.count = 3,
@@ -78,6 +79,7 @@ const struct mdp5_cfg_hw apq8084_config = {
 	.ctl = {
 		.count = 5,
 		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x003fffff,
 	},
 	.pipe_vig = {
 		.count = 4,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +6 -1
index 4e90740..69e35ac 100644
@@ -44,6 +44,11 @@ struct mdp5_lm_block {
 	uint32_t nb_stages;		/* number of stages per blender */
 };
 
+struct mdp5_ctl_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	uint32_t flush_hw_mask;		/* FLUSH register's hardware mask */
+};
+
 struct mdp5_smp_block {
 	int mmb_count;			/* number of SMP MMBs */
 	int mmb_size;			/* MMB: size in bytes */
@@ -55,7 +60,7 @@ struct mdp5_cfg_hw {
 	char  *name;
 
 	struct mdp5_smp_block smp;
-	struct mdp5_sub_block ctl;
+	struct mdp5_ctl_block ctl;
 	struct mdp5_sub_block pipe_vig;
 	struct mdp5_sub_block pipe_rgb;
 	struct mdp5_sub_block pipe_dma;
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +18 -13
index 15136f1..9527ad1 100644
@@ -82,8 +82,6 @@ static void request_pending(struct drm_crtc *crtc, uint32_t pending)
 	mdp_irq_register(&get_kms(crtc)->base, &mdp5_crtc->vblank);
 }
 
-#define mdp5_lm_get_flush(lm)	mdp_ctl_flush_mask_lm(lm)
-
 static void crtc_flush(struct drm_crtc *crtc, u32 flush_mask)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
@@ -110,8 +108,8 @@ static void crtc_flush_all(struct drm_crtc *crtc)
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
 		flush_mask |= mdp5_plane_get_flush(plane);
 	}
-	flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
-	flush_mask |= mdp5_lm_get_flush(mdp5_crtc->lm);
+
+	flush_mask |= mdp_ctl_flush_mask_lm(mdp5_crtc->lm);
 
 	crtc_flush(crtc, flush_mask);
 }
@@ -442,13 +440,14 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
-	struct drm_gem_object *cursor_bo, *old_bo;
+	struct drm_gem_object *cursor_bo, *old_bo = NULL;
 	uint32_t blendcfg, cursor_addr, stride;
 	int ret, bpp, lm;
 	unsigned int depth;
 	enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
 	uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
 	uint32_t roi_w, roi_h;
+	bool cursor_enable = true;
 	unsigned long flags;
 
 	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
@@ -461,7 +460,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
 	if (!handle) {
 		DBG("Cursor off");
-		return mdp5_ctl_set_cursor(mdp5_crtc->ctl, false);
+		cursor_enable = false;
+		goto set_cursor;
 	}
 
 	cursor_bo = drm_gem_object_lookup(dev, file, handle);
@@ -502,11 +502,14 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
 	spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
 
-	ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true);
-	if (ret)
+set_cursor:
+	ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, 0, cursor_enable);
+	if (ret) {
+		dev_err(dev->dev, "failed to %sable cursor: %d\n",
+				cursor_enable ? "en" : "dis", ret);
 		goto end;
+	}
 
-	flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
 	crtc_flush(crtc, flush_mask);
 
 end:
@@ -628,11 +631,13 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf)
 int mdp5_crtc_get_lm(struct drm_crtc *crtc)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return WARN_ON(!crtc) ? -EINVAL : mdp5_crtc->lm;
+}
 
-	if (WARN_ON(!crtc))
-		return -EINVAL;
-
-	return mdp5_crtc->lm;
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return WARN_ON(!crtc) ? NULL : mdp5_crtc->ctl;
 }
 
 /* initialize crtc */
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +215 -32

355 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +23 -49

94 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +11 -2
index f3b6fe8..a17eb9c 100644
@@ -217,12 +217,15 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3);  /* frame+line? */
 
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+
+	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
 }
 
 static void mdp5_encoder_disable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc);
 	int lm = mdp5_crtc_get_lm(encoder->crtc);
 	struct mdp5_interface *intf = &mdp5_encoder->intf;
 	int intfn = mdp5_encoder->intf.num;
@@ -231,9 +234,12 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 	if (WARN_ON(!mdp5_encoder->enabled))
 		return;
 
+	mdp5_ctl_set_encoder_state(ctl, false);
+
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
 
 	/*
 	 * Wait for a vsync so we know the ENABLE=0 latched before
@@ -254,18 +260,21 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc);
+	struct mdp5_interface *intf = &mdp5_encoder->intf;
 	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(mdp5_encoder->enabled))
 		return;
 
-	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
-
 	bs_set(mdp5_encoder, 1);
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
+
+	mdp5_ctl_set_encoder_state(ctl, true);
 
 	mdp5_encoder->enabled = true;
 }
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +1 -0
index 1a6aa49..690edfd 100644
@@ -230,6 +230,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
 uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
 
 int mdp5_crtc_get_lm(struct drm_crtc *crtc);
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc);
 void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
 void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf);
 struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#14 lore raw

PATCH v2 4/4 drm/msm/mdp5: Make the intf connection in config module

In reply to Stephane Viau

Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another.

v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |   8 +++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   4 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 111 ++++++++++++++++++--------------
 3 files changed, 74 insertions(+), 49 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 72c075a..8bee023 100644
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
 		.count = 4,
 		.base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
 	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
 	.max_clk = 200000000,
 };
 
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = {
 		.count = 5,
 		.base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
 	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
 	.max_clk = 320000000,
 };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +4 -0
index 69e35ac..12224d7 100644
@@ -56,6 +56,8 @@ struct mdp5_smp_block {
 	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
 };
 
+#define MDP5_INTF_NUM_MAX	5
+
 struct mdp5_cfg_hw {
 	char  *name;
 
@@ -69,6 +71,8 @@ struct mdp5_cfg_hw {
 	struct mdp5_sub_block ad;
 	struct mdp5_sub_block intf;
 
+	u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+
 	uint32_t max_clk;
 };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +62 -49

139 lines not on this page · raw message

Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#15 lore raw

cover drm/msm: Add display configuration for msm8x16

In reply to Stephane Viau

This patch set contains a couple modifications of the MDP5 register description, followed by the MDP hw configuration of the msm8016 and msm8916 chipsets.

Stephane Viau (5):
drm/msm/mdp5: Update headers (introduce MDP5 domain) drm/msm/mdp5: Separate MDP5 domain from MDSS domain drm/msm/mdp5: Update headers (remove enum mdp5_client_id) drm/msm/mdp5: Get SMP client list from mdp5_cfg drm/msm/mdp5: Add hardware configuration for msm8x16

 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 230 ++++++++++++++++----------------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |  79 ++++++++++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   2 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c |  20 +--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c |  26 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c |   9 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h |   2 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c |  64 ++++-----
 8 files changed, 257 insertions(+), 175 deletions(-)
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#16 lore raw

PATCH 1/5 drm/msm/mdp5: Update headers (introduce MDP5 domain)

This change contains the generated header file for the following change "drm/msm/mdp5: Separate MDP5 domain from MDSS domain".

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 203 +++++++++++++++++++-------------
 1 file changed, 118 insertions(+), 85 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +118 -85
index b4d8716..cb931ca 100644
@@ -8,7 +8,7 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27094 bytes, from 2015-01-23 16:27:31)
+- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  29843 bytes, from 2015-03-09 12:32:38)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2014-06-02 18:31:15)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml      (   2357 bytes, from 2015-01-23 16:20:19)
 
@@ -174,139 +174,172 @@ enum mdp5_data_format {
 #define MDP5_IRQ_INTF2_VSYNC					0x20000000
 #define MDP5_IRQ_INTF3_UNDER_RUN				0x40000000
 #define MDP5_IRQ_INTF3_VSYNC					0x80000000
-#define REG_MDP5_HW_VERSION					0x00000000
+#define REG_MDSS_HW_VERSION					0x00000000
+#define MDSS_HW_VERSION_STEP__MASK				0x0000ffff
+#define MDSS_HW_VERSION_STEP__SHIFT				0
+static inline uint32_t MDSS_HW_VERSION_STEP(uint32_t val)
+{
+	return ((val) << MDSS_HW_VERSION_STEP__SHIFT) & MDSS_HW_VERSION_STEP__MASK;
+}
+#define MDSS_HW_VERSION_MINOR__MASK				0x0fff0000
+#define MDSS_HW_VERSION_MINOR__SHIFT				16
+static inline uint32_t MDSS_HW_VERSION_MINOR(uint32_t val)
+{
+	return ((val) << MDSS_HW_VERSION_MINOR__SHIFT) & MDSS_HW_VERSION_MINOR__MASK;
+}
+#define MDSS_HW_VERSION_MAJOR__MASK				0xf0000000
+#define MDSS_HW_VERSION_MAJOR__SHIFT				28
+static inline uint32_t MDSS_HW_VERSION_MAJOR(uint32_t val)
+{
+	return ((val) << MDSS_HW_VERSION_MAJOR__SHIFT) & MDSS_HW_VERSION_MAJOR__MASK;
+}
+
+#define REG_MDSS_HW_INTR_STATUS					0x00000010
+#define MDSS_HW_INTR_STATUS_INTR_MDP				0x00000001
+#define MDSS_HW_INTR_STATUS_INTR_DSI0				0x00000010
+#define MDSS_HW_INTR_STATUS_INTR_DSI1				0x00000020
+#define MDSS_HW_INTR_STATUS_INTR_HDMI				0x00000100
+#define MDSS_HW_INTR_STATUS_INTR_EDP				0x00001000
 
-#define REG_MDP5_HW_INTR_STATUS					0x00000010
-#define MDP5_HW_INTR_STATUS_INTR_MDP				0x00000001
-#define MDP5_HW_INTR_STATUS_INTR_DSI0				0x00000010
-#define MDP5_HW_INTR_STATUS_INTR_DSI1				0x00000020
-#define MDP5_HW_INTR_STATUS_INTR_HDMI				0x00000100
-#define MDP5_HW_INTR_STATUS_INTR_EDP				0x00001000
+static inline uint32_t __offset_MDP(uint32_t idx)
+{
+	switch (idx) {
+		case 0: return (mdp5_cfg->mdp.base[0]);
+		default: return INVALID_IDX(idx);
+	}
+}
+static inline uint32_t REG_MDP5_MDP(uint32_t i0) { return 0x00000000 + __offset_MDP(i0); }
 
-#define REG_MDP5_MDP_VERSION					0x00000100
-#define MDP5_MDP_VERSION_MINOR__MASK				0x00ff0000
-#define MDP5_MDP_VERSION_MINOR__SHIFT				16
-static inline uint32_t MDP5_MDP_VERSION_MINOR(uint32_t val)
+static inline uint32_t REG_MDP5_MDP_HW_VERSION(uint32_t i0) { return 0x00000000 + __offset_MDP(i0); }
+#define MDP5_MDP_HW_VERSION_STEP__MASK				0x0000ffff
+#define MDP5_MDP_HW_VERSION_STEP__SHIFT				0
+static inline uint32_t MDP5_MDP_HW_VERSION_STEP(uint32_t val)
+{
+	return ((val) << MDP5_MDP_HW_VERSION_STEP__SHIFT) & MDP5_MDP_HW_VERSION_STEP__MASK;
+}
+#define MDP5_MDP_HW_VERSION_MINOR__MASK				0x0fff0000
+#define MDP5_MDP_HW_VERSION_MINOR__SHIFT			16
+static inline uint32_t MDP5_MDP_HW_VERSION_MINOR(uint32_t val)
 {
-	return ((val) << MDP5_MDP_VERSION_MINOR__SHIFT) & MDP5_MDP_VERSION_MINOR__MASK;
+	return ((val) << MDP5_MDP_HW_VERSION_MINOR__SHIFT) & MDP5_MDP_HW_VERSION_MINOR__MASK;
 }
-#define MDP5_MDP_VERSION_MAJOR__MASK				0xf0000000
-#define MDP5_MDP_VERSION_MAJOR__SHIFT				28
-static inline uint32_t MDP5_MDP_VERSION_MAJOR(uint32_t val)
+#define MDP5_MDP_HW_VERSION_MAJOR__MASK				0xf0000000
+#define MDP5_MDP_HW_VERSION_MAJOR__SHIFT			28
+static inline uint32_t MDP5_MDP_HW_VERSION_MAJOR(uint32_t val)
 {
-	return ((val) << MDP5_MDP_VERSION_MAJOR__SHIFT) & MDP5_MDP_VERSION_MAJOR__MASK;
+	return ((val) << MDP5_MDP_HW_VERSION_MAJOR__SHIFT) & MDP5_MDP_HW_VERSION_MAJOR__MASK;
 }
 
-#define REG_MDP5_DISP_INTF_SEL					0x00000104
-#define MDP5_DISP_INTF_SEL_INTF0__MASK				0x000000ff
-#define MDP5_DISP_INTF_SEL_INTF0__SHIFT				0
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf_type val)
+static inline uint32_t REG_MDP5_MDP_DISP_INTF_SEL(uint32_t i0) { return 0x00000004 + __offset_MDP(i0); }
+#define MDP5_MDP_DISP_INTF_SEL_INTF0__MASK			0x000000ff
+#define MDP5_MDP_DISP_INTF_SEL_INTF0__SHIFT			0
+static inline uint32_t MDP5_MDP_DISP_INTF_SEL_INTF0(enum mdp5_intf_type val)
 {
-	return ((val) << MDP5_DISP_INTF_SEL_INTF0__SHIFT) & MDP5_DISP_INTF_SEL_INTF0__MASK;
+	return ((val) << MDP5_MDP_DISP_INTF_SEL_INTF0__SHIFT) & MDP5_MDP_DISP_INTF_SEL_INTF0__MASK;
 }
-#define MDP5_DISP_INTF_SEL_INTF1__MASK				0x0000ff00
-#define MDP5_DISP_INTF_SEL_INTF1__SHIFT				8
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf_type val)
+#define MDP5_MDP_DISP_INTF_SEL_INTF1__MASK			0x0000ff00
+#define MDP5_MDP_DISP_INTF_SEL_INTF1__SHIFT			8
+static inline uint32_t MDP5_MDP_DISP_INTF_SEL_INTF1(enum mdp5_intf_type val)
 {
-	return ((val) << MDP5_DISP_INTF_SEL_INTF1__SHIFT) & MDP5_DISP_INTF_SEL_INTF1__MASK;
+	return ((val) << MDP5_MDP_DISP_INTF_SEL_INTF1__SHIFT) & MDP5_MDP_DISP_INTF_SEL_INTF1__MASK;
 }
-#define MDP5_DISP_INTF_SEL_INTF2__MASK				0x00ff0000
-#define MDP5_DISP_INTF_SEL_INTF2__SHIFT				16
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf_type val)
+#define MDP5_MDP_DISP_INTF_SEL_INTF2__MASK			0x00ff0000
+#define MDP5_MDP_DISP_INTF_SEL_INTF2__SHIFT			16
+static inline uint32_t MDP5_MDP_DISP_INTF_SEL_INTF2(enum mdp5_intf_type val)
 {
-	return ((val) << MDP5_DISP_INTF_SEL_INTF2__SHIFT) & MDP5_DISP_INTF_SEL_INTF2__MASK;
+	return ((val) << MDP5_MDP_DISP_INTF_SEL_INTF2__SHIFT) & MDP5_MDP_DISP_INTF_SEL_INTF2__MASK;
 }
-#define MDP5_DISP_INTF_SEL_INTF3__MASK				0xff000000
-#define MDP5_DISP_INTF_SEL_INTF3__SHIFT				24
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf_type val)
+#define MDP5_MDP_DISP_INTF_SEL_INTF3__MASK			0xff000000
+#define MDP5_MDP_DISP_INTF_SEL_INTF3__SHIFT			24
+static inline uint32_t MDP5_MDP_DISP_INTF_SEL_INTF3(enum mdp5_intf_type val)
 {
-	return ((val) << MDP5_DISP_INTF_SEL_INTF3__SHIFT) & MDP5_DISP_INTF_SEL_INTF3__MASK;
+	return ((val) << MDP5_MDP_DISP_INTF_SEL_INTF3__SHIFT) & MDP5_MDP_DISP_INTF_SEL_INTF3__MASK;
 }
 
-#define REG_MDP5_INTR_EN					0x00000110
+static inline uint32_t REG_MDP5_MDP_INTR_EN(uint32_t i0) { return 0x00000010 + __offset_MDP(i0); }
 
-#define REG_MDP5_INTR_STATUS					0x00000114
+static inline uint32_t REG_MDP5_MDP_INTR_STATUS(uint32_t i0) { return 0x00000014 + __offset_MDP(i0); }
 
-#define REG_MDP5_INTR_CLEAR					0x00000118
+static inline uint32_t REG_MDP5_MDP_INTR_CLEAR(uint32_t i0) { return 0x00000018 + __offset_MDP(i0); }
 
-#define REG_MDP5_HIST_INTR_EN					0x0000011c
+static inline uint32_t REG_MDP5_MDP_HIST_INTR_EN(uint32_t i0) { return 0x0000001c + __offset_MDP(i0); }
 
-#define REG_MDP5_HIST_INTR_STATUS				0x00000120
+static inline uint32_t REG_MDP5_MDP_HIST_INTR_STATUS(uint32_t i0) { return 0x00000020 + __offset_MDP(i0); }
 
-#define REG_MDP5_HIST_INTR_CLEAR				0x00000124
+static inline uint32_t REG_MDP5_MDP_HIST_INTR_CLEAR(uint32_t i0) { return 0x00000024 + __offset_MDP(i0); }
 
-#define REG_MDP5_SPARE_0					0x00000128
-#define MDP5_SPARE_0_SPLIT_DPL_SINGLE_FLUSH_EN			0x00000001
+static inline uint32_t REG_MDP5_MDP_SPARE_0(uint32_t i0) { return 0x00000028 + __offset_MDP(i0); }
+#define MDP5_MDP_SPARE_0_SPLIT_DPL_SINGLE_FLUSH_EN		0x00000001
 
-static inline uint32_t REG_MDP5_SMP_ALLOC_W(uint32_t i0) { return 0x00000180 + 0x4*i0; }
+static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_W(uint32_t i0, uint32_t i1) { return 0x00000080 + __offset_MDP(i0) + 0x4*i1; }
 
-static inline uint32_t REG_MDP5_SMP_ALLOC_W_REG(uint32_t i0) { return 0x00000180 + 0x4*i0; }
-#define MDP5_SMP_ALLOC_W_REG_CLIENT0__MASK			0x000000ff
-#define MDP5_SMP_ALLOC_W_REG_CLIENT0__SHIFT			0
-static inline uint32_t MDP5_SMP_ALLOC_W_REG_CLIENT0(enum mdp5_client_id val)
+static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_W_REG(uint32_t i0, uint32_t i1) { return 0x00000080 + __offset_MDP(i0) + 0x4*i1; }
+#define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__MASK			0x000000ff
+#define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__SHIFT			0
+static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0(enum mdp5_client_id val)
 {
-	return ((val) << MDP5_SMP_ALLOC_W_REG_CLIENT0__SHIFT) & MDP5_SMP_ALLOC_W_REG_CLIENT0__MASK;
+	return ((val) << MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__SHIFT) & MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__MASK;
 }
-#define MDP5_SMP_ALLOC_W_REG_CLIENT1__MASK			0x0000ff00
-#define MDP5_SMP_ALLOC_W_REG_CLIENT1__SHIFT			8
-static inline uint32_t MDP5_SMP_ALLOC_W_REG_CLIENT1(enum mdp5_client_id val)
+#define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__MASK			0x0000ff00
+#define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__SHIFT			8
+static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1(enum mdp5_client_id val)
 {
-	return ((val) << MDP5_SMP_ALLOC_W_REG_CLIENT1__SHIFT) & MDP5_SMP_ALLOC_W_REG_CLIENT1__MASK;
+	return ((val) << MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__SHIFT) & MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__MASK;
 }
-#define MDP5_SMP_ALLOC_W_REG_CLIENT2__MASK			0x00ff0000
-#define MDP5_SMP_ALLOC_W_REG_CLIENT2__SHIFT			16
-static inline uint32_t MDP5_SMP_ALLOC_W_REG_CLIENT2(enum mdp5_client_id val)
+#define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__MASK			0x00ff0000
+#define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__SHIFT			16
+static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2(enum mdp5_client_id val)
 {
-	return ((val) << MDP5_SMP_ALLOC_W_REG_CLIENT2__SHIFT) & MDP5_SMP_ALLOC_W_REG_CLIENT2__MASK;
+	return ((val) << MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__SHIFT) & MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__MASK;
 }
 
-static inline uint32_t REG_MDP5_SMP_ALLOC_R(uint32_t i0) { return 0x00000230 + 0x4*i0; }
+static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_R(uint32_t i0, uint32_t i1) { return 0x00000130 + __offset_MDP(i0) + 0x4*i1; }
 
-static inline uint32_t REG_MDP5_SMP_ALLOC_R_REG(uint32_t i0) { return 0x00000230 + 0x4*i0; }
-#define MDP5_SMP_ALLOC_R_REG_CLIENT0__MASK			0x000000ff
-#define MDP5_SMP_ALLOC_R_REG_CLIENT0__SHIFT			0
-static inline uint32_t MDP5_SMP_ALLOC_R_REG_CLIENT0(enum mdp5_client_id val)
+static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_R_REG(uint32_t i0, uint32_t i1) { return 0x00000130 + __offset_MDP(i0) + 0x4*i1; }
+#define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__MASK			0x000000ff
+#define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__SHIFT			0
+static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0(enum mdp5_client_id val)
 {
-	return ((val) << MDP5_SMP_ALLOC_R_REG_CLIENT0__SHIFT) & MDP5_SMP_ALLOC_R_REG_CLIENT0__MASK;
+	return ((val) << MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__SHIFT) & MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__MASK;
 }
-#define MDP5_SMP_ALLOC_R_REG_CLIENT1__MASK			0x0000ff00
-#define MDP5_SMP_ALLOC_R_REG_CLIENT1__SHIFT			8
-static inline uint32_t MDP5_SMP_ALLOC_R_REG_CLIENT1(enum mdp5_client_id val)
+#define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__MASK			0x0000ff00
+#define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__SHIFT			8
+static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1(enum mdp5_client_id val)
 {
-	return ((val) << MDP5_SMP_ALLOC_R_REG_CLIENT1__SHIFT) & MDP5_SMP_ALLOC_R_REG_CLIENT1__MASK;
+	return ((val) << MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__SHIFT) & MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__MASK;
 }
-#define MDP5_SMP_ALLOC_R_REG_CLIENT2__MASK			0x00ff0000
-#define MDP5_SMP_ALLOC_R_REG_CLIENT2__SHIFT			16
-static inline uint32_t MDP5_SMP_ALLOC_R_REG_CLIENT2(enum mdp5_client_id val)
+#define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__MASK			0x00ff0000
+#define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__SHIFT			16
+static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2(enum mdp5_client_id val)
 {
-	return ((val) << MDP5_SMP_ALLOC_R_REG_CLIENT2__SHIFT) & MDP5_SMP_ALLOC_R_REG_CLIENT2__MASK;
+	return ((val) << MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__SHIFT) & MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__MASK;
 }
 
 static inline uint32_t __offset_IGC(enum mdp5_igc_type idx)
 {
 	switch (idx) {
-		case IGC_VIG: return 0x00000300;
-		case IGC_RGB: return 0x00000310;
-		case IGC_DMA: return 0x00000320;
-		case IGC_DSPP: return 0x00000400;
+		case IGC_VIG: return 0x00000200;
+		case IGC_RGB: return 0x00000210;
+		case IGC_DMA: return 0x00000220;
+		case IGC_DSPP: return 0x00000300;
 		default: return INVALID_IDX(idx);
 	}
 }
-static inline uint32_t REG_MDP5_IGC(enum mdp5_igc_type i0) { return 0x00000000 + __offset_IGC(i0); }
+static inline uint32_t REG_MDP5_MDP_IGC(uint32_t i0, enum mdp5_igc_type i1) { return 0x00000000 + __offset_MDP(i0) + __offset_IGC(i1); }
 
-static inline uint32_t REG_MDP5_IGC_LUT(enum mdp5_igc_type i0, uint32_t i1) { return 0x00000000 + __offset_IGC(i0) + 0x4*i1; }
+static inline uint32_t REG_MDP5_MDP_IGC_LUT(uint32_t i0, enum mdp5_igc_type i1, uint32_t i2) { return 0x00000000 + __offset_MDP(i0) + __offset_IGC(i1) + 0x4*i2; }
 
-static inline uint32_t REG_MDP5_IGC_LUT_REG(enum mdp5_igc_type i0, uint32_t i1) { return 0x00000000 + __offset_IGC(i0) + 0x4*i1; }
-#define MDP5_IGC_LUT_REG_VAL__MASK				0x00000fff
-#define MDP5_IGC_LUT_REG_VAL__SHIFT				0
-static inline uint32_t MDP5_IGC_LUT_REG_VAL(uint32_t val)
+static inline uint32_t REG_MDP5_MDP_IGC_LUT_REG(uint32_t i0, enum mdp5_igc_type i1, uint32_t i2) { return 0x00000000 + __offset_MDP(i0) + __offset_IGC(i1) + 0x4*i2; }
+#define MDP5_MDP_IGC_LUT_REG_VAL__MASK				0x00000fff
+#define MDP5_MDP_IGC_LUT_REG_VAL__SHIFT				0
+static inline uint32_t MDP5_MDP_IGC_LUT_REG_VAL(uint32_t val)
 {
-	return ((val) << MDP5_IGC_LUT_REG_VAL__SHIFT) & MDP5_IGC_LUT_REG_VAL__MASK;
+	return ((val) << MDP5_MDP_IGC_LUT_REG_VAL__SHIFT) & MDP5_MDP_IGC_LUT_REG_VAL__MASK;
 }
-#define MDP5_IGC_LUT_REG_INDEX_UPDATE				0x02000000
-#define MDP5_IGC_LUT_REG_DISABLE_PIPE_0				0x10000000
-#define MDP5_IGC_LUT_REG_DISABLE_PIPE_1				0x20000000
-#define MDP5_IGC_LUT_REG_DISABLE_PIPE_2				0x40000000
+#define MDP5_MDP_IGC_LUT_REG_INDEX_UPDATE			0x02000000
+#define MDP5_MDP_IGC_LUT_REG_DISABLE_PIPE_0			0x10000000
+#define MDP5_MDP_IGC_LUT_REG_DISABLE_PIPE_1			0x20000000
+#define MDP5_MDP_IGC_LUT_REG_DISABLE_PIPE_2			0x40000000
 
 #define REG_MDP5_SPLIT_DPL_EN					0x000003f4
 
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#17 lore raw

PATCH 2/5 drm/msm/mdp5: Separate MDP5 domain from MDSS domain

In reply to Stephane Viau

MDP block is actually contained inside the MDSS block. For some chipsets, the base address of the MDP registers is different from the current (assumed) 0x100 offset.

Like CTL and LM blocks, this changes introduce a dynamic offset for the MDP instance, which can be found out at runtime, once the MDSS HW version is read.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |  8 ++++++++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |  1 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | 20 ++++++++++----------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 26 +++++++++++++-------------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c |  9 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h |  2 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | 20 ++++++++++----------
 7 files changed, 48 insertions(+), 38 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 6c467fb..f786c70 100644
@@ -24,6 +24,10 @@ const struct mdp5_cfg_hw *mdp5_cfg = NULL;
 
 const struct mdp5_cfg_hw msm8x74_config = {
 	.name = "msm8x74",
+	.mdp = {
+		.count = 1,
+		.base = { 0x00100 },
+	},
 	.smp = {
 		.mmb_count = 22,
 		.mmb_size = 4096,
@@ -75,6 +79,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
 
 const struct mdp5_cfg_hw apq8084_config = {
 	.name = "apq8084",
+	.mdp = {
+		.count = 1,
+		.base = { 0x00100 },
+	},
 	.smp = {
 		.mmb_count = 44,
 		.mmb_size = 8192,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +1 -0
index 93bee92..11f3e86 100644
@@ -61,6 +61,7 @@ struct mdp5_smp_block {
 struct mdp5_cfg_hw {
 	char  *name;
 
+	struct mdp5_sub_block mdp;
 	struct mdp5_smp_block smp;
 	struct mdp5_ctl_block ctl;
 	struct mdp5_sub_block pipe_vig;
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +10 -10
index 7c0adf5..0fa7fce 100644
@@ -112,31 +112,31 @@ static void set_display_intf(struct mdp5_kms *mdp5_kms,
 	u32 intf_sel;
 
 	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
-	intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
+	intf_sel = mdp5_read(mdp5_kms, REG_MDP5_MDP_DISP_INTF_SEL(0));
 
 	switch (intf->num) {
 	case 0:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF0__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF0(intf->type);
+		intf_sel &= ~MDP5_MDP_DISP_INTF_SEL_INTF0__MASK;
+		intf_sel |= MDP5_MDP_DISP_INTF_SEL_INTF0(intf->type);
 		break;
 	case 1:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF1__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF1(intf->type);
+		intf_sel &= ~MDP5_MDP_DISP_INTF_SEL_INTF1__MASK;
+		intf_sel |= MDP5_MDP_DISP_INTF_SEL_INTF1(intf->type);
 		break;
 	case 2:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF2__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF2(intf->type);
+		intf_sel &= ~MDP5_MDP_DISP_INTF_SEL_INTF2__MASK;
+		intf_sel |= MDP5_MDP_DISP_INTF_SEL_INTF2(intf->type);
 		break;
 	case 3:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF3__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF3(intf->type);
+		intf_sel &= ~MDP5_MDP_DISP_INTF_SEL_INTF3__MASK;
+		intf_sel |= MDP5_MDP_DISP_INTF_SEL_INTF3(intf->type);
 		break;
 	default:
 		BUG();
 		break;
 	}
 
-	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel);
+	mdp5_write(mdp5_kms, REG_MDP5_MDP_DISP_INTF_SEL(0), intf_sel);
 	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
 }
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +13 -13
index a940710..33bd4c6 100644
@@ -23,7 +23,7 @@
 
 void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask)
 {
-	mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_INTR_EN, irqmask);
+	mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_MDP_INTR_EN(0), irqmask);
 }
 
 static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
@@ -35,8 +35,8 @@ void mdp5_irq_preinstall(struct msm_kms *kms)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 	mdp5_enable(mdp5_kms);
-	mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff);
-	mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
+	mdp5_write(mdp5_kms, REG_MDP5_MDP_INTR_CLEAR(0), 0xffffffff);
+	mdp5_write(mdp5_kms, REG_MDP5_MDP_INTR_EN(0), 0x00000000);
 	mdp5_disable(mdp5_kms);
 }
 
@@ -61,7 +61,7 @@ void mdp5_irq_uninstall(struct msm_kms *kms)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 	mdp5_enable(mdp5_kms);
-	mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
+	mdp5_write(mdp5_kms, REG_MDP5_MDP_INTR_EN(0), 0x00000000);
 	mdp5_disable(mdp5_kms);
 }
 
@@ -73,8 +73,8 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms)
 	unsigned int id;
 	uint32_t status;
 
-	status = mdp5_read(mdp5_kms, REG_MDP5_INTR_STATUS);
-	mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, status);
+	status = mdp5_read(mdp5_kms, REG_MDP5_MDP_INTR_STATUS(0));
+	mdp5_write(mdp5_kms, REG_MDP5_MDP_INTR_CLEAR(0), status);
 
 	VERB("status=%08x", status);
 
@@ -91,13 +91,13 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
 	uint32_t intr;
 
-	intr = mdp5_read(mdp5_kms, REG_MDP5_HW_INTR_STATUS);
+	intr = mdp5_read(mdp5_kms, REG_MDSS_HW_INTR_STATUS);
 
 	VERB("intr=%08x", intr);
 
-	if (intr & MDP5_HW_INTR_STATUS_INTR_MDP) {
+	if (intr & MDSS_HW_INTR_STATUS_INTR_MDP) {
 		mdp5_irq_mdp(mdp_kms);
-		intr &= ~MDP5_HW_INTR_STATUS_INTR_MDP;
+		intr &= ~MDSS_HW_INTR_STATUS_INTR_MDP;
 	}
 
 	while (intr) {
@@ -128,10 +128,10 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
  * can register to get their irq's delivered
  */
 
-#define VALID_IRQS  (MDP5_HW_INTR_STATUS_INTR_DSI0 | \
-		MDP5_HW_INTR_STATUS_INTR_DSI1 | \
-		MDP5_HW_INTR_STATUS_INTR_HDMI | \
-		MDP5_HW_INTR_STATUS_INTR_EDP)
+#define VALID_IRQS  (MDSS_HW_INTR_STATUS_INTR_DSI0 | \
+		MDSS_HW_INTR_STATUS_INTR_DSI1 | \
+		MDSS_HW_INTR_STATUS_INTR_HDMI | \
+		MDSS_HW_INTR_STATUS_INTR_EDP)
 
 static void mdp5_hw_mask_irq(struct irq_data *irqd)
 {
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +5 -4
index 73729e9..a733074 100644
@@ -58,7 +58,7 @@ static int mdp5_hw_init(struct msm_kms *kms)
 	 */
 
 	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0);
+	mdp5_write(mdp5_kms, REG_MDP5_MDP_DISP_INTF_SEL(0), 0);
 	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
 
 	mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
@@ -296,11 +296,11 @@ static void read_hw_revision(struct mdp5_kms *mdp5_kms,
 	uint32_t version;
 
 	mdp5_enable(mdp5_kms);
-	version = mdp5_read(mdp5_kms, REG_MDP5_MDP_VERSION);
+	version = mdp5_read(mdp5_kms, REG_MDSS_HW_VERSION);
 	mdp5_disable(mdp5_kms);
 
-	*major = FIELD(version, MDP5_MDP_VERSION_MAJOR);
-	*minor = FIELD(version, MDP5_MDP_VERSION_MINOR);
+	*major = FIELD(version, MDSS_HW_VERSION_MAJOR);
+	*minor = FIELD(version, MDSS_HW_VERSION_MINOR);
 
 	DBG("MDP5 version v%d.%d", *major, *minor);
 }
@@ -343,6 +343,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 
 	mdp5_kms->dev = dev;
 
+	/* mdp5_kms->mmio actually represents the MDSS base address */
 	mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
 	if (IS_ERR(mdp5_kms->mmio)) {
 		ret = PTR_ERR(mdp5_kms->mmio);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +1 -1
index 690edfd..6efa5c6 100644
@@ -54,7 +54,7 @@ struct mdp5_kms {
 
 	/*
 	 * lock to protect access to global resources: ie., following register:
-	 *	- REG_MDP5_DISP_INTF_SEL
+	 *	- REG_MDP5_MDP_DISP_INTF_SEL
 	 */
 	spinlock_t resource_lock;
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +10 -10
index 1f795af89..361c064 100644
@@ -43,7 +43,7 @@
  *     set.
  *
  *  2) mdp5_smp_configure():
- *     As hw is programmed, before FLUSH, MDP5_SMP_ALLOC registers
+ *     As hw is programmed, before FLUSH, MDP5_MDP_SMP_ALLOC registers
  *     are configured for the union(pending, inuse)
  *
  *  3) mdp5_smp_commit():
@@ -237,25 +237,25 @@ static void update_smp_state(struct mdp5_smp *smp,
 		int idx = blk / 3;
 		int fld = blk % 3;
 
-		val = mdp5_read(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(idx));
+		val = mdp5_read(mdp5_kms, REG_MDP5_MDP_SMP_ALLOC_W_REG(0, idx));
 
 		switch (fld) {
 		case 0:
-			val &= ~MDP5_SMP_ALLOC_W_REG_CLIENT0__MASK;
-			val |= MDP5_SMP_ALLOC_W_REG_CLIENT0(cid);
+			val &= ~MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__MASK;
+			val |= MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0(cid);
 			break;
 		case 1:
-			val &= ~MDP5_SMP_ALLOC_W_REG_CLIENT1__MASK;
-			val |= MDP5_SMP_ALLOC_W_REG_CLIENT1(cid);
+			val &= ~MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__MASK;
+			val |= MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1(cid);
 			break;
 		case 2:
-			val &= ~MDP5_SMP_ALLOC_W_REG_CLIENT2__MASK;
-			val |= MDP5_SMP_ALLOC_W_REG_CLIENT2(cid);
+			val &= ~MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__MASK;
+			val |= MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2(cid);
 			break;
 		}
 
-		mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(idx), val);
-		mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_R_REG(idx), val);
+		mdp5_write(mdp5_kms, REG_MDP5_MDP_SMP_ALLOC_W_REG(0, idx), val);
+		mdp5_write(mdp5_kms, REG_MDP5_MDP_SMP_ALLOC_R_REG(0, idx), val);
 	}
 }
 
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#18 lore raw

PATCH 3/5 drm/msm/mdp5: Update headers (remove enum mdp5_client_id)

In reply to Stephane Viau

This patch contains the generated header file of the following change "drm/msm/mdp5: Get SMP client list from mdp5_cfg".

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 41 ++++++---------------------------
 1 file changed, 7 insertions(+), 34 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +7 -34
index cb931ca..b4e2624 100644
@@ -8,7 +8,7 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  29843 bytes, from 2015-03-09 12:32:38)
+- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  28872 bytes, from 2015-03-09 12:40:51)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2014-06-02 18:31:15)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml      (   2357 bytes, from 2015-01-23 16:20:19)
 
@@ -97,33 +97,6 @@ enum mdp5_pipe_bwc {
 	BWC_Q_MED = 2,
 };
 
-enum mdp5_client_id {
-	CID_UNUSED = 0,
-	CID_VIG0_Y = 1,
-	CID_VIG0_CR = 2,
-	CID_VIG0_CB = 3,
-	CID_VIG1_Y = 4,
-	CID_VIG1_CR = 5,
-	CID_VIG1_CB = 6,
-	CID_VIG2_Y = 7,
-	CID_VIG2_CR = 8,
-	CID_VIG2_CB = 9,
-	CID_DMA0_Y = 10,
-	CID_DMA0_CR = 11,
-	CID_DMA0_CB = 12,
-	CID_DMA1_Y = 13,
-	CID_DMA1_CR = 14,
-	CID_DMA1_CB = 15,
-	CID_RGB0 = 16,
-	CID_RGB1 = 17,
-	CID_RGB2 = 18,
-	CID_VIG3_Y = 19,
-	CID_VIG3_CR = 20,
-	CID_VIG3_CB = 21,
-	CID_RGB3 = 22,
-	CID_MAX = 23,
-};
-
 enum mdp5_cursor_format {
 	CURSOR_FMT_ARGB8888 = 0,
 	CURSOR_FMT_ARGB1555 = 2,
@@ -276,19 +249,19 @@ static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_W(uint32_t i0, uint32_t i1) { retu
 static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_W_REG(uint32_t i0, uint32_t i1) { return 0x00000080 + __offset_MDP(i0) + 0x4*i1; }
 #define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__MASK			0x000000ff
 #define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__SHIFT			0
-static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0(enum mdp5_client_id val)
+static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0(uint32_t val)
 {
 	return ((val) << MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__SHIFT) & MDP5_MDP_SMP_ALLOC_W_REG_CLIENT0__MASK;
 }
 #define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__MASK			0x0000ff00
 #define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__SHIFT			8
-static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1(enum mdp5_client_id val)
+static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1(uint32_t val)
 {
 	return ((val) << MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__SHIFT) & MDP5_MDP_SMP_ALLOC_W_REG_CLIENT1__MASK;
 }
 #define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__MASK			0x00ff0000
 #define MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__SHIFT			16
-static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2(enum mdp5_client_id val)
+static inline uint32_t MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2(uint32_t val)
 {
 	return ((val) << MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__SHIFT) & MDP5_MDP_SMP_ALLOC_W_REG_CLIENT2__MASK;
 }
@@ -298,19 +271,19 @@ static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_R(uint32_t i0, uint32_t i1) { retu
 static inline uint32_t REG_MDP5_MDP_SMP_ALLOC_R_REG(uint32_t i0, uint32_t i1) { return 0x00000130 + __offset_MDP(i0) + 0x4*i1; }
 #define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__MASK			0x000000ff
 #define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__SHIFT			0
-static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0(enum mdp5_client_id val)
+static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0(uint32_t val)
 {
 	return ((val) << MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__SHIFT) & MDP5_MDP_SMP_ALLOC_R_REG_CLIENT0__MASK;
 }
 #define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__MASK			0x0000ff00
 #define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__SHIFT			8
-static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1(enum mdp5_client_id val)
+static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1(uint32_t val)
 {
 	return ((val) << MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__SHIFT) & MDP5_MDP_SMP_ALLOC_R_REG_CLIENT1__MASK;
 }
 #define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__MASK			0x00ff0000
 #define MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__SHIFT			16
-static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2(enum mdp5_client_id val)
+static inline uint32_t MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2(uint32_t val)
 {
 	return ((val) << MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__SHIFT) & MDP5_MDP_SMP_ALLOC_R_REG_CLIENT2__MASK;
 }
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#19 lore raw

PATCH 4/5 drm/msm/mdp5: Get SMP client list from mdp5_cfg

In reply to Stephane Viau

SMP blocks are configured for specific client IDs (ports). These client IDs can be different from one chip to another for a given pipe.

e.g.: DMA0 pipe fetch Y component is connected to:
- port #10 for MDP5 v1.3
- port #4 for MDP5 v1.6

In order to be compatible for upcoming versions of MDP5, the client ID list is passed through the MDP5 config module rather than using a list of hard-coded enum values.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 20 ++++++++++++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |  1 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | 44 ++++++++++++++++++---------------
 3 files changed, 41 insertions(+), 24 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +16 -4
index f786c70..96ea6dd 100644
@@ -31,6 +31,11 @@ const struct mdp5_cfg_hw msm8x74_config = {
 	.smp = {
 		.mmb_count = 22,
 		.mmb_size = 4096,
+		.clients = {
+			[SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
+			[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
+			[SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
+		},
 	},
 	.ctl = {
 		.count = 5,
@@ -86,11 +91,18 @@ const struct mdp5_cfg_hw apq8084_config = {
 	.smp = {
 		.mmb_count = 44,
 		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
+			[SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
+			[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
+			[SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
+			[SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
+		},
 		.reserved_state[0] = GENMASK(7, 0),	/* first 8 MMBs */
-		.reserved[CID_RGB0] = 2,
-		.reserved[CID_RGB1] = 2,
-		.reserved[CID_RGB2] = 2,
-		.reserved[CID_RGB3] = 2,
+		.reserved = {
+			/* Two SMP blocks are statically tied to RGB pipes: */
+			[16] = 2, [17] = 2, [18] = 2, [22] = 2,
+		},
 	},
 	.ctl = {
 		.count = 5,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +1 -0
index 11f3e86..3a551b0 100644
@@ -52,6 +52,7 @@ struct mdp5_ctl_block {
 struct mdp5_smp_block {
 	int mmb_count;			/* number of SMP MMBs */
 	int mmb_size;			/* MMB: size in bytes */
+	uint32_t clients[MAX_CLIENTS];	/* SMP port allocation /pipe */
 	mdp5_smp_state_t reserved_state;/* SMP MMBs statically allocated */
 	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
 };
drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +24 -20

79 lines not on this page · raw message

Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#20 lore raw

PATCH 5/5 drm/msm/mdp5: Add hardware configuration for msm8x16

In reply to Stephane Viau

This change adds the hw configuration for msm8x16 chipsets in mdp5_cfg module.

Note that only one external display interface is present in this configuration (DSI) but has not been enabled yet. It will be enabled once drm/msm driver supports DSI connectors.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 51 ++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +50 -1
index 96ea6dd..9ff7ac1 100644
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -150,10 +150,59 @@ const struct mdp5_cfg_hw apq8084_config = {
 	.max_clk = 320000000,
 };
 
+const struct mdp5_cfg_hw msm8x16_config = {
+	.name = "msm8x16",
+	.mdp = {
+		.count = 1,
+		.base = { 0x01000 },
+	},
+	.smp = {
+		.mmb_count = 8,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x05000 },
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x15000, 0x17000 },
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x25000 },
+	},
+	.lm = {
+		.count = 2, /* LM0 and LM3 */
+		.base = { 0x45000, 0x48000 },
+		.nb_stages = 5,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x55000 },
+
+	},
+	.intf = {
+		.count = 1, /* INTF_1 */
+		.base = { 0x6B800 },
+	},
+	/* TODO enable .intfs[] with [1] = INTF_DSI, once DSI is implemented */
+	.max_clk = 320000000,
+};
+
 static const struct mdp5_cfg_handler cfg_handlers[] = {
 	{ .revision = 0, .config = { .hw = &msm8x74_config } },
 	{ .revision = 2, .config = { .hw = &msm8x74_config } },
 	{ .revision = 3, .config = { .hw = &apq8084_config } },
+	{ .revision = 6, .config = { .hw = &msm8x16_config } },
 };
 
 
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#21 lore raw

Re: [PATCH 5/5] drm/msm/mdp5: Add hardware configuration for msm8x16

Hi,

Quoted 60 lines · Stephane Viau

This change adds the hw configuration for msm8x16 chipsets in mdp5_cfg module.

Note that only one external display interface is present in this configuration (DSI) but has not been enabled yet. It will be enabled once drm/msm driver supports DSI connectors.

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 51 ++++++++++++++++++++++++++++++++-
  1 file changed, 50 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +34 -1
index 96ea6dd..9ff7ac1 100644
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 and
@@ -150,10 +150,59 @@ const struct mdp5_cfg_hw apq8084_config = {
  	.max_clk = 320000000,
  };
 
+const struct mdp5_cfg_hw msm8x16_config = {
+	.name = "msm8x16",
+	.mdp = {
+		.count = 1,
+		.base = { 0x01000 },
+	},
+	.smp = {
+		.mmb_count = 8,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x05000 },
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x15000, 0x17000 },
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x25000 },
+	},
+	.lm = {
+		.count = 2, /* LM0 and LM3 */
+		.base = { 0x45000, 0x48000 },

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 195

Quoted 10 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +10 -0
+		.nb_stages = 5,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x55000 },
+
+	},
+	.intf = {
+		.count = 1, /* INTF_1 */
+		.base = { 0x6B800 },

We would need to put the other non-existent INTF_0, INTF_2 and INTF_3 base addresses here too, so that the writes to REG_MDP5_INTF_TIMING_ENGINE_EN in the patch "Make the intf connection in config module" access the correct registers.

Archit

Quoted 14 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +6 -0
+	},
+	/* TODO enable .intfs[] with [1] = INTF_DSI, once DSI is implemented */
+	.max_clk = 320000000,
+};
+
  static const struct mdp5_cfg_handler cfg_handlers[] = {
  	{ .revision = 0, .config = { .hw = &msm8x74_config } },
  	{ .revision = 2, .config = { .hw = &msm8x74_config } },
  	{ .revision = 3, .config = { .hw = &apq8084_config } },
+	{ .revision = 6, .config = { .hw = &msm8x16_config } },
  };
 
 
Signature · 6 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#22 lore raw

Re: [PATCH 5/5] drm/msm/mdp5: Add hardware configuration for msm8x16

Hi,

Quoted 73 lines

Hi,

Quoted 70 lines · Stephane Viau

This change adds the hw configuration for msm8x16 chipsets in mdp5_cfg module.

Note that only one external display interface is present in this configuration (DSI) but has not been enabled yet. It will be enabled once drm/msm driver supports DSI connectors.

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 51
++++++++++++++++++++++++++++++++-
  1 file changed, 50 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -1
index 96ea6dd..9ff7ac1 100644
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or

modify
* it under the terms of the GNU General Public License version 2 and

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +40 -0
@@ -150,10 +150,59 @@ const struct mdp5_cfg_hw apq8084_config = {
  	.max_clk = 320000000,
  };
 
+const struct mdp5_cfg_hw msm8x16_config = {
+	.name = "msm8x16",
+	.mdp = {
+		.count = 1,
+		.base = { 0x01000 },
+	},
+	.smp = {
+		.mmb_count = 8,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x05000 },
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x15000, 0x17000 },
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x25000 },
+	},
+	.lm = {
+		.count = 2, /* LM0 and LM3 */
+		.base = { 0x45000, 0x48000 },
+		.nb_stages = 5,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x55000 },
+
+	},
Quoted 8 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 195

Quoted 3 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +3 -0
+	.intf = {
+		.count = 1, /* INTF_1 */
+		.base = { 0x6B800 },

We would need to put the other non-existent INTF_0, INTF_2 and INTF_3 base addresses here too, so that the writes to REG_MDP5_INTF_TIMING_ENGINE_EN in the patch "Make the intf connection in config module" access the correct registers.

You are referring here to the discussion we had in "drm/msm/mdp5: Make the intf connection in config module"[1]...

Let me clarify:
We see these faults when interfaces are *present* but not *supported* by the driver, where:
- *present* means that the interfaces are physically implemented in HW
and therefore need to be reflected by "intf.base" addresses
- *supported* means that the msm KMS driver is actually able to drive an
interface
If you look at mdp5_cfg.c in "drm/msm/mdp5: Make the intf connection in config module"[1], 4 interfaces (intf.base) are present (for apq8084), but only 2 are supported (intfs[])...
What I meant is that even though our driver cannot support all interfaces present in a chip, we still need to disable them in mdp5_kms_init(). (BTW, this is probably due to my bootloader enabling the DSI whereas the msm KMS driver does not support it as of yet - and thus leads to artifacts/underflow on my eDP panel.)

So to answer your comment, it doesn't make too much sense to define base addresses for interfaces that are not present in a chip. Instead I'd prefer to check if intf.base is not NULL before writing in REG_MDP5_INTF_TIMING_ENGINE_EN registers.. and avoid some INVALID_INDEX BUGs ;-).

I'm sending out a v3 for "drm/msm/mdp5: Make the intf connection in config module" in a minute...

[1] http://lists.freedesktop.org/archives/dri-devel/2015-March/078651.html

Quoted 28 lines

Archit

Quoted 5 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +2 -0
+	},
+	/* TODO enable .intfs[] with [1] = INTF_DSI, once DSI is implemented
 */

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 207

Quoted 10 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +4 -0
+	.max_clk = 320000000,
+};
+
  static const struct mdp5_cfg_handler cfg_handlers[] = {
  	{ .revision = 0, .config = { .hw = &msm8x74_config } },
  	{ .revision = 2, .config = { .hw = &msm8x74_config } },
  	{ .revision = 3, .config = { .hw = &apq8084_config } },
+	{ .revision = 6, .config = { .hw = &msm8x16_config } },
  };
 

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 4 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
#23 lore raw

v3 cover drm/msm: preparation for WB/DSI connectors

WB and DSI support are in the pipe and will come out soon. Before that, we need to prepare the MDP5 driver so we can support these connectors.

v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]
v3: add sanity check before writing in INTF_TIMING_ENGINE_EN registers

Note:
"drm/msm: Add display configuration for msm8x16" patch set depends on "drm/msm: preparation for WB/DSI connectors" patch set.

Stephane Viau (4):
drm/msm/mdp5: Update generated header files drm/msm/mdp5: Enhance operation mode for pipeline configuration drm/msm/mdp5: Add START signal to kick off certain pipelines drm/msm/mdp5: Make the intf connection in config module

 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h     |  68 +++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |  10 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  15 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  70 ++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 326 +++++++++++++++++++++++++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  75 +++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  40 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     | 100 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |  49 ++++-
 9 files changed, 522 insertions(+), 231 deletions(-)
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#24 lore raw

PATCH v3 1/4 drm/msm/mdp5: Update generated header files

Prepare for pipeline operation mode configuration, in particular for DSI and WB modes.

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 68 ++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 35 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +33 -35
index c276624..095a54c 100644
@@ -8,7 +8,7 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27229 bytes, from 2015-02-10 17:00:41)
+- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml            (  27094 bytes, from 2015-01-23 16:27:31)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2014-06-02 18:31:15)
 - /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml      (   2357 bytes, from 2015-01-23 16:20:19)
 
@@ -37,11 +37,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 
-enum mdp5_intf {
+enum mdp5_intf_type {
+	INTF_DISABLED = 0,
 	INTF_DSI = 1,
 	INTF_HDMI = 3,
 	INTF_LCDC = 5,
 	INTF_eDP = 9,
+	INTF_VIRTUAL = 100,
+	INTF_WB = 101,
 };
 
 enum mdp5_intfnum {
@@ -67,11 +70,11 @@ enum mdp5_pipe {
 
 enum mdp5_ctl_mode {
 	MODE_NONE = 0,
-	MODE_ROT0 = 1,
-	MODE_ROT1 = 2,
-	MODE_WB0 = 3,
-	MODE_WB1 = 4,
-	MODE_WFD = 5,
+	MODE_WB_0_BLOCK = 1,
+	MODE_WB_1_BLOCK = 2,
+	MODE_WB_0_LINE = 3,
+	MODE_WB_1_LINE = 4,
+	MODE_WB_2_LINE = 5,
 };
 
 enum mdp5_pack_3d {
@@ -144,30 +147,25 @@ enum mdp5_data_format {
 	DATA_FORMAT_YUV = 1,
 };
 
-#define MDP5_IRQ_INTF0_WB_ROT_COMP				0x00000001
-#define MDP5_IRQ_INTF1_WB_ROT_COMP				0x00000002
-#define MDP5_IRQ_INTF2_WB_ROT_COMP				0x00000004
-#define MDP5_IRQ_INTF3_WB_ROT_COMP				0x00000008
-#define MDP5_IRQ_INTF0_WB_WFD					0x00000010
-#define MDP5_IRQ_INTF1_WB_WFD					0x00000020
-#define MDP5_IRQ_INTF2_WB_WFD					0x00000040
-#define MDP5_IRQ_INTF3_WB_WFD					0x00000080
-#define MDP5_IRQ_INTF0_PING_PONG_COMP				0x00000100
-#define MDP5_IRQ_INTF1_PING_PONG_COMP				0x00000200
-#define MDP5_IRQ_INTF2_PING_PONG_COMP				0x00000400
-#define MDP5_IRQ_INTF3_PING_PONG_COMP				0x00000800
-#define MDP5_IRQ_INTF0_PING_PONG_RD_PTR				0x00001000
-#define MDP5_IRQ_INTF1_PING_PONG_RD_PTR				0x00002000
-#define MDP5_IRQ_INTF2_PING_PONG_RD_PTR				0x00004000
-#define MDP5_IRQ_INTF3_PING_PONG_RD_PTR				0x00008000
-#define MDP5_IRQ_INTF0_PING_PONG_WR_PTR				0x00010000
-#define MDP5_IRQ_INTF1_PING_PONG_WR_PTR				0x00020000
-#define MDP5_IRQ_INTF2_PING_PONG_WR_PTR				0x00040000
-#define MDP5_IRQ_INTF3_PING_PONG_WR_PTR				0x00080000
-#define MDP5_IRQ_INTF0_PING_PONG_AUTO_REF			0x00100000
-#define MDP5_IRQ_INTF1_PING_PONG_AUTO_REF			0x00200000
-#define MDP5_IRQ_INTF2_PING_PONG_AUTO_REF			0x00400000
-#define MDP5_IRQ_INTF3_PING_PONG_AUTO_REF			0x00800000
+#define MDP5_IRQ_WB_0_DONE					0x00000001
+#define MDP5_IRQ_WB_1_DONE					0x00000002
+#define MDP5_IRQ_WB_2_DONE					0x00000010
+#define MDP5_IRQ_PING_PONG_0_DONE				0x00000100
+#define MDP5_IRQ_PING_PONG_1_DONE				0x00000200
+#define MDP5_IRQ_PING_PONG_2_DONE				0x00000400
+#define MDP5_IRQ_PING_PONG_3_DONE				0x00000800
+#define MDP5_IRQ_PING_PONG_0_RD_PTR				0x00001000
+#define MDP5_IRQ_PING_PONG_1_RD_PTR				0x00002000
+#define MDP5_IRQ_PING_PONG_2_RD_PTR				0x00004000
+#define MDP5_IRQ_PING_PONG_3_RD_PTR				0x00008000
+#define MDP5_IRQ_PING_PONG_0_WR_PTR				0x00010000
+#define MDP5_IRQ_PING_PONG_1_WR_PTR				0x00020000
+#define MDP5_IRQ_PING_PONG_2_WR_PTR				0x00040000
+#define MDP5_IRQ_PING_PONG_3_WR_PTR				0x00080000
+#define MDP5_IRQ_PING_PONG_0_AUTO_REF				0x00100000
+#define MDP5_IRQ_PING_PONG_1_AUTO_REF				0x00200000
+#define MDP5_IRQ_PING_PONG_2_AUTO_REF				0x00400000
+#define MDP5_IRQ_PING_PONG_3_AUTO_REF				0x00800000
 #define MDP5_IRQ_INTF0_UNDER_RUN				0x01000000
 #define MDP5_IRQ_INTF0_VSYNC					0x02000000
 #define MDP5_IRQ_INTF1_UNDER_RUN				0x04000000
@@ -202,25 +200,25 @@ static inline uint32_t MDP5_MDP_VERSION_MAJOR(uint32_t val)
 #define REG_MDP5_DISP_INTF_SEL					0x00000104
 #define MDP5_DISP_INTF_SEL_INTF0__MASK				0x000000ff
 #define MDP5_DISP_INTF_SEL_INTF0__SHIFT				0
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF0(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF0__SHIFT) & MDP5_DISP_INTF_SEL_INTF0__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF1__MASK				0x0000ff00
 #define MDP5_DISP_INTF_SEL_INTF1__SHIFT				8
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF1(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF1__SHIFT) & MDP5_DISP_INTF_SEL_INTF1__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF2__MASK				0x00ff0000
 #define MDP5_DISP_INTF_SEL_INTF2__SHIFT				16
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF2(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF2__SHIFT) & MDP5_DISP_INTF_SEL_INTF2__MASK;
 }
 #define MDP5_DISP_INTF_SEL_INTF3__MASK				0xff000000
 #define MDP5_DISP_INTF_SEL_INTF3__SHIFT				24
-static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf val)
+static inline uint32_t MDP5_DISP_INTF_SEL_INTF3(enum mdp5_intf_type val)
 {
 	return ((val) << MDP5_DISP_INTF_SEL_INTF3__SHIFT) & MDP5_DISP_INTF_SEL_INTF3__MASK;
 }
Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#25 lore raw

PATCH v3 2/4 drm/msm/mdp5: Enhance operation mode for pipeline configuration

In reply to Stephane Viau

DSI and WB interfaces need a more complex pipeline configuration than the current mdp5_ctl_set_intf().

For example, memory output connections need to be selected for WB. Interface mode (Video vs. Command modes) also need to be configured for DSI.

This change takes care of configuring the whole pipeline as far as operation mode goes. DSI and WB interfaces will be added later.

v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |  4 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    | 39 ++-----------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 91 +++++++++++++++++++++++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  3 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 29 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c     | 16 ++++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     | 48 ++++++++++++---
 7 files changed, 159 insertions(+), 71 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +4 -0
index dba4d52..4e90740 100644
@@ -84,6 +84,10 @@ const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_hn
 struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_hnd);
 int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_hnd);
 
+#define mdp5_cfg_intf_is_virtual(intf_type) ({	\
+	typeof(intf_type) __val = (intf_type);	\
+	(__val) >= INTF_VIRTUAL ? true : false; })
+
 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
 		uint32_t major, uint32_t minor);
 void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_hnd);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +4 -35
index bfba236..15136f1 100644
@@ -611,48 +611,17 @@ void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file)
 }
 
 /* set interface for routing crtc->encoder: */
-void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
-		enum mdp5_intf intf_id)
+void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
-	uint32_t intf_sel;
-	unsigned long flags;
+	int lm = mdp5_crtc_get_lm(crtc);
 
 	/* now that we know what irq's we want: */
-	mdp5_crtc->err.irqmask = intf2err(intf);
-	mdp5_crtc->vblank.irqmask = intf2vblank(intf);
+	mdp5_crtc->err.irqmask = intf2err(intf->num);
+	mdp5_crtc->vblank.irqmask = intf2vblank(lm, intf);
 	mdp_irq_update(&mdp5_kms->base);
 
-	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
-	intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
-
-	switch (intf) {
-	case 0:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF0__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF0(intf_id);
-		break;
-	case 1:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF1__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF1(intf_id);
-		break;
-	case 2:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF2__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF2(intf_id);
-		break;
-	case 3:
-		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF3__MASK;
-		intf_sel |= MDP5_DISP_INTF_SEL_INTF3(intf_id);
-		break;
-	default:
-		BUG();
-		break;
-	}
-
-	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel);
-	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
-
-	DBG("%s: intf_sel=%08x", mdp5_crtc->name, intf_sel);
 	mdp5_ctl_set_intf(mdp5_crtc->ctl, intf);
 }
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +81 -10

121 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +2 -1
index ad48788..271d5ac 100644
@@ -34,7 +34,8 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm);
  */
 struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc);
 
-int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf);
+struct mdp5_interface;
+int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, struct mdp5_interface *intf);
 
 int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable);
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +14 -15
index a09fa58..f3b6fe8 100644
@@ -23,8 +23,7 @@
 
 struct mdp5_encoder {
 	struct drm_encoder base;
-	int intf;
-	enum mdp5_intf intf_id;
+	struct mdp5_interface intf;
 	spinlock_t intf_lock;	/* protect REG_MDP5_INTF_* registers */
 	bool enabled;
 	uint32_t bsc;
@@ -126,7 +125,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
 	struct drm_device *dev = encoder->dev;
 	struct drm_connector *connector;
-	int intf = mdp5_encoder->intf;
+	int intf = mdp5_encoder->intf.num;
 	uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
 	uint32_t display_v_start, display_v_end;
 	uint32_t hsync_start_x, hsync_end_x;
@@ -188,7 +187,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
 	 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
 	 */
-	if (mdp5_encoder->intf_id == INTF_eDP) {
+	if (mdp5_encoder->intf.type == INTF_eDP) {
 		display_v_start += mode->htotal - mode->hsync_start;
 		display_v_end -= mode->hsync_start - mode->hdisplay;
 	}
@@ -224,14 +223,16 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
-	int intf = mdp5_encoder->intf;
+	int lm = mdp5_crtc_get_lm(encoder->crtc);
+	struct mdp5_interface *intf = &mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(!mdp5_encoder->enabled))
 		return;
 
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 
 	/*
@@ -242,7 +243,7 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 	 * the settings changes for the new modeset (like new
 	 * scanout buffer) don't latch properly..
 	 */
-	mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf));
+	mdp_irq_wait(&mdp5_kms->base, intf2vblank(lm, intf));
 
 	bs_set(mdp5_encoder, 0);
 
@@ -253,18 +254,17 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
-	int intf = mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(mdp5_encoder->enabled))
 		return;
 
-	mdp5_crtc_set_intf(encoder->crtc, mdp5_encoder->intf,
-			mdp5_encoder->intf_id);
+	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
 
 	bs_set(mdp5_encoder, 1);
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
-	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
 
 	mdp5_encoder->enabled = true;
@@ -278,8 +278,8 @@ static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
 };
 
 /* initialize encoder */
-struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
-		enum mdp5_intf intf_id)
+struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
+				struct mdp5_interface *intf)
 {
 	struct drm_encoder *encoder = NULL;
 	struct mdp5_encoder *mdp5_encoder;
@@ -291,8 +291,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
 		goto fail;
 	}
 
-	mdp5_encoder->intf = intf;
-	mdp5_encoder->intf_id = intf_id;
+	memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf));
 	encoder = &mdp5_encoder->base;
 
 	spin_lock_init(&mdp5_encoder->intf_lock);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +14 -2
index 92b61db..390d9d2 100644
@@ -223,8 +223,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 	}
 
 	if (priv->hdmi) {
+		struct mdp5_interface intf = {
+				.num	= 3,
+				.type	= INTF_HDMI,
+				.mode	= MDP5_INTF_MODE_NONE,
+		};
+
 		/* Construct encoder for HDMI: */
-		encoder = mdp5_encoder_init(dev, 3, INTF_HDMI);
+		encoder = mdp5_encoder_init(dev, &intf);
 		if (IS_ERR(encoder)) {
 			dev_err(dev->dev, "failed to construct encoder\n");
 			ret = PTR_ERR(encoder);
@@ -242,8 +248,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 	}
 
 	if (priv->edp) {
+		struct mdp5_interface intf = {
+				.num	= 0,
+				.type	= INTF_eDP,
+				.mode	= MDP5_INTF_MODE_NONE,
+		};
+
 		/* Construct encoder for eDP: */
-		encoder = mdp5_encoder_init(dev, 0, INTF_eDP);
+		encoder = mdp5_encoder_init(dev, &intf);
 		if (IS_ERR(encoder)) {
 			dev_err(dev->dev, "failed to construct eDP encoder\n");
 			ret = PTR_ERR(encoder);
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +40 -8

76 lines not on this page · raw message

Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#26 lore raw

PATCH v3 3/4 drm/msm/mdp5: Add START signal to kick off certain pipelines

In reply to Stephane Viau

Some interfaces (WB, DSI Command Mode) need to be kicked off through a START Signal. This signal needs to be sent at the right time and requests in some cases to keep track of the pipeline status (eg: whether pipeline registers are flushed AND output WB buffers are ready, in case of WB interface).

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |   2 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |   7 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  31 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 247 ++++++++++++++++++++++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  72 +++-----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  13 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |   1 +
 7 files changed, 276 insertions(+), 97 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +2 -0
index c078f30..72c075a 100644
@@ -31,6 +31,7 @@ const struct mdp5_cfg_hw msm8x74_config = {
 	.ctl = {
 		.count = 5,
 		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x0003ffff,
 	},
 	.pipe_vig = {
 		.count = 3,
@@ -78,6 +79,7 @@ const struct mdp5_cfg_hw apq8084_config = {
 	.ctl = {
 		.count = 5,
 		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x003fffff,
 	},
 	.pipe_vig = {
 		.count = 4,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +6 -1
index 4e90740..69e35ac 100644
@@ -44,6 +44,11 @@ struct mdp5_lm_block {
 	uint32_t nb_stages;		/* number of stages per blender */
 };
 
+struct mdp5_ctl_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	uint32_t flush_hw_mask;		/* FLUSH register's hardware mask */
+};
+
 struct mdp5_smp_block {
 	int mmb_count;			/* number of SMP MMBs */
 	int mmb_size;			/* MMB: size in bytes */
@@ -55,7 +60,7 @@ struct mdp5_cfg_hw {
 	char  *name;
 
 	struct mdp5_smp_block smp;
-	struct mdp5_sub_block ctl;
+	struct mdp5_ctl_block ctl;
 	struct mdp5_sub_block pipe_vig;
 	struct mdp5_sub_block pipe_rgb;
 	struct mdp5_sub_block pipe_dma;
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +18 -13
index 15136f1..9527ad1 100644
@@ -82,8 +82,6 @@ static void request_pending(struct drm_crtc *crtc, uint32_t pending)
 	mdp_irq_register(&get_kms(crtc)->base, &mdp5_crtc->vblank);
 }
 
-#define mdp5_lm_get_flush(lm)	mdp_ctl_flush_mask_lm(lm)
-
 static void crtc_flush(struct drm_crtc *crtc, u32 flush_mask)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
@@ -110,8 +108,8 @@ static void crtc_flush_all(struct drm_crtc *crtc)
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
 		flush_mask |= mdp5_plane_get_flush(plane);
 	}
-	flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
-	flush_mask |= mdp5_lm_get_flush(mdp5_crtc->lm);
+
+	flush_mask |= mdp_ctl_flush_mask_lm(mdp5_crtc->lm);
 
 	crtc_flush(crtc, flush_mask);
 }
@@ -442,13 +440,14 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
-	struct drm_gem_object *cursor_bo, *old_bo;
+	struct drm_gem_object *cursor_bo, *old_bo = NULL;
 	uint32_t blendcfg, cursor_addr, stride;
 	int ret, bpp, lm;
 	unsigned int depth;
 	enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
 	uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
 	uint32_t roi_w, roi_h;
+	bool cursor_enable = true;
 	unsigned long flags;
 
 	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
@@ -461,7 +460,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
 	if (!handle) {
 		DBG("Cursor off");
-		return mdp5_ctl_set_cursor(mdp5_crtc->ctl, false);
+		cursor_enable = false;
+		goto set_cursor;
 	}
 
 	cursor_bo = drm_gem_object_lookup(dev, file, handle);
@@ -502,11 +502,14 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
 	spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
 
-	ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true);
-	if (ret)
+set_cursor:
+	ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, 0, cursor_enable);
+	if (ret) {
+		dev_err(dev->dev, "failed to %sable cursor: %d\n",
+				cursor_enable ? "en" : "dis", ret);
 		goto end;
+	}
 
-	flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
 	crtc_flush(crtc, flush_mask);
 
 end:
@@ -628,11 +631,13 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf)
 int mdp5_crtc_get_lm(struct drm_crtc *crtc)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return WARN_ON(!crtc) ? -EINVAL : mdp5_crtc->lm;
+}
 
-	if (WARN_ON(!crtc))
-		return -EINVAL;
-
-	return mdp5_crtc->lm;
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return WARN_ON(!crtc) ? NULL : mdp5_crtc->ctl;
 }
 
 /* initialize crtc */
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +215 -32

355 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +23 -49

94 lines not on this page · raw message

drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +11 -2
index f3b6fe8..a17eb9c 100644
@@ -217,12 +217,15 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3);  /* frame+line? */
 
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+
+	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
 }
 
 static void mdp5_encoder_disable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc);
 	int lm = mdp5_crtc_get_lm(encoder->crtc);
 	struct mdp5_interface *intf = &mdp5_encoder->intf;
 	int intfn = mdp5_encoder->intf.num;
@@ -231,9 +234,12 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
 	if (WARN_ON(!mdp5_encoder->enabled))
 		return;
 
+	mdp5_ctl_set_encoder_state(ctl, false);
+
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
 
 	/*
 	 * Wait for a vsync so we know the ENABLE=0 latched before
@@ -254,18 +260,21 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
 {
 	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
 	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc);
+	struct mdp5_interface *intf = &mdp5_encoder->intf;
 	int intfn = mdp5_encoder->intf.num;
 	unsigned long flags;
 
 	if (WARN_ON(mdp5_encoder->enabled))
 		return;
 
-	mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf);
-
 	bs_set(mdp5_encoder, 1);
 	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
 	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
 	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
+
+	mdp5_ctl_set_encoder_state(ctl, true);
 
 	mdp5_encoder->enabled = true;
 }
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +1 -0
index 1a6aa49..690edfd 100644
@@ -230,6 +230,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
 uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
 
 int mdp5_crtc_get_lm(struct drm_crtc *crtc);
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc);
 void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
 void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf);
 struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#27 lore raw

Re: [PATCH v3 3/4] drm/msm/mdp5: Add START signal to kick off certain pipelines

Hi Stephane,

Quoted 30 lines · Stephane Viau

Some interfaces (WB, DSI Command Mode) need to be kicked off through a START Signal. This signal needs to be sent at the right time and requests in some cases to keep track of the pipeline status (eg: whether pipeline registers are flushed AND output WB buffers are ready, in case of WB interface).

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |   2 +
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |   7 +-
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  31 ++--
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 247 ++++++++++++++++++++++++----
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  72 +++-----
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  13 +-
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |   1 +
  7 files changed, 276 insertions(+), 97 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -0
index c078f30..72c075a 100644
@@ -31,6 +31,7 @@ const struct mdp5_cfg_hw msm8x74_config = {
  	.ctl = {
  		.count = 5,
  		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x0003ffff,
  	},
  	.pipe_vig = {
  		.count = 3,

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 82

Quoted 4 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -0
@@ -78,6 +79,7 @@ const struct mdp5_cfg_hw apq8084_config = {
  	.ctl = {
  		.count = 5,
  		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x003fffff,

msm8x16 would require a flush_hw_mask too, it should be 0x32a59 if I'm not wrong. Could you please add it for the next revision, or as a part of the 8x16 hw cfg patch?

Thanks,
Archit

Signature · 6 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#28 lore raw

Re: [PATCH v3 3/4] drm/msm/mdp5: Add START signal to kick off certain pipelines

Hi Archit,

Quoted 35 lines

Hi Stephane,

Quoted 32 lines · Stephane Viau

Some interfaces (WB, DSI Command Mode) need to be kicked off through a START Signal. This signal needs to be sent at the right time and requests in some cases to keep track of the pipeline status (eg: whether pipeline registers are flushed AND output WB buffers are ready, in case of WB interface).

---
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |   2 +
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |   7 +-
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  31 ++--
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 247
++++++++++++++++++++++++----
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  72 +++-----
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  13 +-
  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |   1 +
  7 files changed, 276 insertions(+), 97 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -0
index c078f30..72c075a 100644
@@ -31,6 +31,7 @@ const struct mdp5_cfg_hw msm8x74_config = {
  	.ctl = {
  		.count = 5,
  		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x0003ffff,
  	},
  	.pipe_vig = {
  		.count = 3,
@@ -78,6 +79,7 @@ const struct mdp5_cfg_hw apq8084_config = {
Quoted 8 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 82

Quoted 4 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -0
  	.ctl = {
  		.count = 5,
  		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x003fffff,

msm8x16 would require a flush_hw_mask too, it should be 0x32a59 if I'm not wrong. Could you please add it for the next revision, or as a part of the 8x16 hw cfg patch?

Correct; thanks for pointing this out.

IMO, this value should be 0x4003ffff because the fields are actually present in the register (even though the interfaces/pipes.etc. are not). Anyway, these bits won't be accessed because the driver won't even allow the usage of the corresponding resources.

I will update in the v2 of "drm/msm/mdp5: Add hardware configuration for msm8x16".

Thanks,
Stephane.

Quoted 13 lines

Thanks,
Archit

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 9 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#29 lore raw

Re: [PATCH v3 3/4] drm/msm/mdp5: Add START signal to kick off certain pipelines

Quoted 46 lines · Stéphane Viau

Hi Archit,

Quoted 35 lines

Hi Stephane,

Quoted 32 lines · Stephane Viau

Some interfaces (WB, DSI Command Mode) need to be kicked off through a START Signal. This signal needs to be sent at the right time and requests in some cases to keep track of the pipeline status (eg: whether pipeline registers are flushed AND output WB buffers are ready, in case of WB interface).

---
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c     |   2 +
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h     |   7 +-
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c    |  31 ++--
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c     | 247
++++++++++++++++++++++++----
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h     |  72 +++-----
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c |  13 +-
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h     |   1 +
   7 files changed, 276 insertions(+), 97 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -0
index c078f30..72c075a 100644
@@ -31,6 +31,7 @@ const struct mdp5_cfg_hw msm8x74_config = {
   	.ctl = {
   		.count = 5,
   		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x0003ffff,
   	},
   	.pipe_vig = {
   		.count = 3,
@@ -78,6 +79,7 @@ const struct mdp5_cfg_hw apq8084_config = {
Quoted 8 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 82

Quoted 4 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -0
   	.ctl = {
   		.count = 5,
   		.base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+		.flush_hw_mask = 0x003fffff,

msm8x16 would require a flush_hw_mask too, it should be 0x32a59 if I'm not wrong. Could you please add it for the next revision, or as a part of the 8x16 hw cfg patch?

Quoted 7 lines

Correct; thanks for pointing this out.

IMO, this value should be 0x4003ffff because the fields are actually present in the register (even though the interfaces/pipes.etc. are not). Anyway, these bits won't be accessed because the driver won't even allow the usage of the corresponding resources.

Okay, that makes sense.

Quoted 6 lines

I will update in the v2 of "drm/msm/mdp5: Add hardware configuration for msm8x16".

Thanks,
Stephane.

Thanks!
Archit

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#30 lore raw

PATCH v3 4/4 drm/msm/mdp5: Make the intf connection in config module

In reply to Stephane Viau

Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another.

v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]
v3: add sanity check before writing in INTF_TIMING_ENGINE_EN registers

---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c |   8 +++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h |   4 ++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 112 ++++++++++++++++++--------------
 3 files changed, 75 insertions(+), 49 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +8 -0
index 72c075a..8bee023 100644
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = {
 		.count = 4,
 		.base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
 	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
 	.max_clk = 200000000,
 };
 
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = {
 		.count = 5,
 		.base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
 	},
+	.intfs = {
+		[0] = INTF_eDP,
+		[3] = INTF_HDMI,
+	},
 	.max_clk = 320000000,
 };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +4 -0
index 69e35ac..12224d7 100644
@@ -56,6 +56,8 @@ struct mdp5_smp_block {
 	int reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
 };
 
+#define MDP5_INTF_NUM_MAX	5
+
 struct mdp5_cfg_hw {
 	char  *name;
 
@@ -69,6 +71,8 @@ struct mdp5_cfg_hw {
 	struct mdp5_sub_block ad;
 	struct mdp5_sub_block intf;
 
+	u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+
 	uint32_t max_clk;
 };
 
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +63 -49

140 lines not on this page · raw message

Signature · 8 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#31 lore raw

Re: [PATCH 5/5] drm/msm/mdp5: Add hardware configuration for msm8x16

In reply to Stéphane Viau
Quoted 87 lines · Stéphane Viau

Hi,

Quoted 73 lines

Hi,

Quoted 70 lines · Stephane Viau

This change adds the hw configuration for msm8x16 chipsets in mdp5_cfg module.

Note that only one external display interface is present in this configuration (DSI) but has not been enabled yet. It will be enabled once drm/msm driver supports DSI connectors.

---
   drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 51
++++++++++++++++++++++++++++++++-
   1 file changed, 50 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +1 -1
index 96ea6dd..9ff7ac1 100644
@@ -1,5 +1,5 @@
   /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
    *
    * This program is free software; you can redistribute it and/or

modify
* it under the terms of the GNU General Public License version 2 and

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +40 -0
@@ -150,10 +150,59 @@ const struct mdp5_cfg_hw apq8084_config = {
   	.max_clk = 320000000,
   };
 
+const struct mdp5_cfg_hw msm8x16_config = {
+	.name = "msm8x16",
+	.mdp = {
+		.count = 1,
+		.base = { 0x01000 },
+	},
+	.smp = {
+		.mmb_count = 8,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x05000 },
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x15000, 0x17000 },
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x25000 },
+	},
+	.lm = {
+		.count = 2, /* LM0 and LM3 */
+		.base = { 0x45000, 0x48000 },
+		.nb_stages = 5,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x55000 },
+
+	},
Quoted 8 lines

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c const struct mdp5_cfg_hw apq8084_config = { · line 195

Quoted 3 lines
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +3 -0
+	.intf = {
+		.count = 1, /* INTF_1 */
+		.base = { 0x6B800 },

We would need to put the other non-existent INTF_0, INTF_2 and INTF_3 base addresses here too, so that the writes to REG_MDP5_INTF_TIMING_ENGINE_EN in the patch "Make the intf connection in config module" access the correct registers.

You are referring here to the discussion we had in "drm/msm/mdp5: Make the intf connection in config module"[1]...

Quoted 15 lines

Let me clarify:
We see these faults when interfaces are *present* but not *supported* by the driver, where:
- *present* means that the interfaces are physically implemented in HW
and therefore need to be reflected by "intf.base" addresses
- *supported* means that the msm KMS driver is actually able to drive an
interface
If you look at mdp5_cfg.c in "drm/msm/mdp5: Make the intf connection in config module"[1], 4 interfaces (intf.base) are present (for apq8084), but only 2 are supported (intfs[])...
What I meant is that even though our driver cannot support all interfaces present in a chip, we still need to disable them in mdp5_kms_init(). (BTW, this is probably due to my bootloader enabling the DSI whereas the msm KMS driver does not support it as of yet - and thus leads to artifacts/underflow on my eDP panel.)

Okay, I get it now. I think I wasn't sure about whether INTF_DISABLED represents *present* or *supported*. Thanks for the clarification.

Quoted 6 lines

So to answer your comment, it doesn't make too much sense to define base addresses for interfaces that are not present in a chip. Instead I'd prefer to check if intf.base is not NULL before writing in REG_MDP5_INTF_TIMING_ENGINE_EN registers.. and avoid some INVALID_INDEX BUGs ;-).

That sounds good. Thanks.

Archit

Signature · 6 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#32 lore raw

PATCH 1/2 rnndb: Separate MDP5 domain from MDSS domain

In reply to Stephane Viau

MDP block is actually contained inside the MDSS block. For some chipsets, the base address of the MDP registers is different from the current (assumed) 0x100 offset.

Like CTL and LM blocks, this changes introduce a dynamic offset for the MDP instance, which can be found out at runtime, once the MDSS HW version is read.

---
 rnndb/mdp/mdp5.xml | 123 +++++++++++++++++++++++++++++------------------------
 1 file changed, 67 insertions(+), 56 deletions(-)
rnndb/mdp/mdp5.xml +67 -56
index db2e15c..aedaa7c 100644
@@ -9,6 +9,22 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 <domain name="VBIF" width="32">
 </domain>
 
+<domain name="MDSS" width="32">
+	<reg32 offset="0x00000" name="HW_VERSION">
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00010" name="HW_INTR_STATUS">
+		<bitfield name="INTR_MDP"  pos="0"  type="boolean"/>
+		<bitfield name="INTR_DSI0" pos="4"  type="boolean"/>
+		<bitfield name="INTR_DSI1" pos="5"  type="boolean"/>
+		<bitfield name="INTR_HDMI" pos="8"  type="boolean"/>
+		<bitfield name="INTR_EDP"  pos="12" type="boolean"/>
+	</reg32>
+</domain>
+
 <domain name="MDP5" width="32">
 
 	<enum name="mdp5_intf_type">
@@ -149,64 +165,59 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 		<bitfield name="CLIENT2" low="16" high="23" type="mdp5_client_id"/>
 	</bitset>
 
-	<reg32 offset="0x00000" name="HW_VERSION"/>
-	<reg32 offset="0x00010" name="HW_INTR_STATUS">
-		<bitfield name="INTR_MDP"  pos="0"  type="boolean"/>
-		<bitfield name="INTR_DSI0" pos="4"  type="boolean"/>
-		<bitfield name="INTR_DSI1" pos="5"  type="boolean"/>
-		<bitfield name="INTR_HDMI" pos="8"  type="boolean"/>
-		<bitfield name="INTR_EDP"  pos="12" type="boolean"/>
-	</reg32>
-
-	<reg32 offset="0x00100" name="MDP_VERSION">
-		<bitfield name="MINOR" low="16" high="23" type="uint"/>
-		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
-	</reg32>
+	<!-- Even though there is 1 MDP, length=2 to force dynamic offset usage -->
+	<array doffsets="mdp5_cfg->mdp.base[0]" name="MDP" length="2" stride="0x1000">
+		<reg32 offset="0x00000" name="HW_VERSION">
+			<bitfield name="STEP" low="0" high="15" type="uint"/>
+			<bitfield name="MINOR" low="16" high="27" type="uint"/>
+			<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+		</reg32>
 
-	<reg32 offset="0x00104" name="DISP_INTF_SEL">
-		<bitfield name="INTF0" low="0"  high="7"  type="mdp5_intf_type"/>
-		<bitfield name="INTF1" low="8"  high="15" type="mdp5_intf_type"/>
-		<bitfield name="INTF2" low="16" high="23" type="mdp5_intf_type"/>
-		<bitfield name="INTF3" low="24" high="31" type="mdp5_intf_type"/>
-	</reg32>
-	<reg32 offset="0x00110" name="INTR_EN" type="MDP5_IRQ"/>
-	<reg32 offset="0x00114" name="INTR_STATUS" type="MDP5_IRQ"/>
-	<reg32 offset="0x00118" name="INTR_CLEAR" type="MDP5_IRQ"/>
-	<reg32 offset="0x0011C" name="HIST_INTR_EN"/>
-	<reg32 offset="0x00120" name="HIST_INTR_STATUS"/>
-	<reg32 offset="0x00124" name="HIST_INTR_CLEAR"/>
-	<reg32 offset="0x00128" name="SPARE_0">
-		<bitfield name="SPLIT_DPL_SINGLE_FLUSH_EN" pos="0"/>
-	</reg32>
+		<reg32 offset="0x00004" name="DISP_INTF_SEL">
+			<bitfield name="INTF0" low="0"  high="7"  type="mdp5_intf_type"/>
+			<bitfield name="INTF1" low="8"  high="15" type="mdp5_intf_type"/>
+			<bitfield name="INTF2" low="16" high="23" type="mdp5_intf_type"/>
+			<bitfield name="INTF3" low="24" high="31" type="mdp5_intf_type"/>
+		</reg32>
+		<reg32 offset="0x00010" name="INTR_EN" type="MDP5_IRQ"/>
+		<reg32 offset="0x00014" name="INTR_STATUS" type="MDP5_IRQ"/>
+		<reg32 offset="0x00018" name="INTR_CLEAR" type="MDP5_IRQ"/>
+		<reg32 offset="0x0001C" name="HIST_INTR_EN"/>
+		<reg32 offset="0x00020" name="HIST_INTR_STATUS"/>
+		<reg32 offset="0x00024" name="HIST_INTR_CLEAR"/>
+		<reg32 offset="0x00028" name="SPARE_0">
+			<bitfield name="SPLIT_DPL_SINGLE_FLUSH_EN" pos="0"/>
+		</reg32>
 
-	<array offset="0x00180" name="SMP_ALLOC_W" length="8" stride="4">
-		<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
-	</array>
-	<array offset="0x00230" name="SMP_ALLOC_R" length="8" stride="4">
-		<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
-	</array>
+		<array offset="0x00080" name="SMP_ALLOC_W" length="8" stride="4">
+			<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
+		</array>
+		<array offset="0x00130" name="SMP_ALLOC_R" length="8" stride="4">
+			<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
+		</array>
 
-	<enum name="mdp5_igc_type">
-		<value name="IGC_VIG" value="0"/>		<!-- 0x300 -->
-		<value name="IGC_RGB" value="1"/>		<!-- 0x310 -->
-		<value name="IGC_DMA" value="2"/>		<!-- 0x320 -->
-		<value name="IGC_DSPP" value="3"/>		<!-- 0x400 -->
-	</enum>
-	<array offsets="0x00300,0x00310,0x00320,0x00400" name="IGC" length="3" stride="0x10" index="mdp5_igc_type">
-		<array offset="0x00" name="LUT" length="3" stride="4">
-			<reg32 offset="0" name="REG">
-				<bitfield name="VAL" low="0" high="11"/>
-				<bitfield name="INDEX_UPDATE" pos="25" type="boolean"/>
-				<!--
-					not sure about these:
-						/* INDEX_UPDATE */
-						data = (1 << 25) | (((~(1 << blk_idx)) & 0x7) << 28);
-						MDSS_MDP_REG_WRITE(offset, (cfg->c0_c1_data[0] & 0xFFF) | data);
-				 -->
-				<bitfield name="DISABLE_PIPE_0" pos="28" type="boolean"/>
-				<bitfield name="DISABLE_PIPE_1" pos="29" type="boolean"/>
-				<bitfield name="DISABLE_PIPE_2" pos="30" type="boolean"/>
-			</reg32>
+		<enum name="mdp5_igc_type">
+			<value name="IGC_VIG" value="0"/>		<!-- 0x200 -->
+			<value name="IGC_RGB" value="1"/>		<!-- 0x210 -->
+			<value name="IGC_DMA" value="2"/>		<!-- 0x220 -->
+			<value name="IGC_DSPP" value="3"/>		<!-- 0x300 -->
+		</enum>
+		<array offsets="0x00200,0x00210,0x00220,0x00300" name="IGC" length="3" stride="0x10" index="mdp5_igc_type">
+			<array offset="0x00" name="LUT" length="3" stride="4">
+				<reg32 offset="0" name="REG">
+					<bitfield name="VAL" low="0" high="11"/>
+					<bitfield name="INDEX_UPDATE" pos="25" type="boolean"/>
+					<!--
+						not sure about these:
+							/* INDEX_UPDATE */
+							data = (1 << 25) | (((~(1 << blk_idx)) & 0x7) << 28);
+							MDSS_MDP_REG_WRITE(offset, (cfg->c0_c1_data[0] & 0xFFF) | data);
+					-->
+					<bitfield name="DISABLE_PIPE_0" pos="28" type="boolean"/>
+					<bitfield name="DISABLE_PIPE_1" pos="29" type="boolean"/>
+					<bitfield name="DISABLE_PIPE_2" pos="30" type="boolean"/>
+				</reg32>
+			</array>
 		</array>
 	</array>
 
@@ -224,7 +235,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 		<bitfield name="INTF2_TG_SYNC" pos="8" type="boolean"/>
 	</reg32>
 <!-- check length/index.. -->
-    <array doffsets="mdp5_cfg->ctl.base[0],mdp5_cfg->ctl.base[1],mdp5_cfg->ctl.base[2],mdp5_cfg->ctl.base[3],mdp5_cfg->ctl.base[4]" name="CTL" length="5" stride="0x400">
+	<array doffsets="mdp5_cfg->ctl.base[0],mdp5_cfg->ctl.base[1],mdp5_cfg->ctl.base[2],mdp5_cfg->ctl.base[3],mdp5_cfg->ctl.base[4]" name="CTL" length="5" stride="0x400">
 		<array offsets="0x000,0x004,0x008,0x00C,0x010,0x024" name="LAYER" length="6" stride="4">
 			<reg32 offset="0" name="REG">
 				<bitfield name="VIG0"  low="0"  high="2"  type="mdp_mixer_stage_id"/>
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
#33 lore raw

PATCH 2/2 rnndb: Do not use enum mdp5_client_id to configure SMP

SMP blocks are configured for specific client IDs (ports). These client IDs can be different from one chip to another for a given pipe.

e.g.: DMA0 pipe fetch Y component is connected to:
- port #10 for MDP5 v1.3
- port #4 for MDP5 v1.6

In order to be compatible for upcoming versions of MDP5, the client ID list is passed through the MDP5 config module rather than using a list of hard-coded enum values.

---
 rnndb/mdp/mdp5.xml | 34 ++++------------------------------
 1 file changed, 4 insertions(+), 30 deletions(-)
rnndb/mdp/mdp5.xml +4 -30
index aedaa7c..423249a 100644
@@ -91,33 +91,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 		<value name="BWC_Q_MED"    value="2"/>
 	</enum>
 
-	<enum name="mdp5_client_id">
-		<value name="CID_UNUSED"  value="0"/>
-		<value name="CID_VIG0_Y"  value="1"/>
-		<value name="CID_VIG0_CR" value="2"/>
-		<value name="CID_VIG0_CB" value="3"/>
-		<value name="CID_VIG1_Y"  value="4"/>
-		<value name="CID_VIG1_CR" value="5"/>
-		<value name="CID_VIG1_CB" value="6"/>
-		<value name="CID_VIG2_Y"  value="7"/>
-		<value name="CID_VIG2_CR" value="8"/>
-		<value name="CID_VIG2_CB" value="9"/>
-		<value name="CID_DMA0_Y"  value="10"/>
-		<value name="CID_DMA0_CR" value="11"/>
-		<value name="CID_DMA0_CB" value="12"/>
-		<value name="CID_DMA1_Y"  value="13"/>
-		<value name="CID_DMA1_CR" value="14"/>
-		<value name="CID_DMA1_CB" value="15"/>
-		<value name="CID_RGB0"    value="16"/>
-		<value name="CID_RGB1"    value="17"/>
-		<value name="CID_RGB2"    value="18"/>
-		<value name="CID_VIG3_Y"  value="19"/>
-		<value name="CID_VIG3_CR" value="20"/>
-		<value name="CID_VIG3_CB" value="21"/>
-		<value name="CID_RGB3"    value="22"/>
-		<value name="CID_MAX"     value="23"/>
-	</enum>
-
 	<enum name="mdp5_cursor_format">
 		<value name="CURSOR_FMT_ARGB8888" value="0"/>
 		<value name="CURSOR_FMT_ARGB1555" value="2"/>
@@ -160,9 +133,10 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 	</bitset>
 
 	<bitset name="mdp5_smp_alloc" inline="yes">
-		<bitfield name="CLIENT0" low="0"  high="7"  type="mdp5_client_id"/>
-		<bitfield name="CLIENT1" low="8"  high="15" type="mdp5_client_id"/>
-		<bitfield name="CLIENT2" low="16" high="23" type="mdp5_client_id"/>
+        <!-- Use "mdp5_cfg->mdp.smp.clients[enum mdp5_pipe]" instead -->
+		<bitfield name="CLIENT0" low="0"  high="7"  type="uint"/>
+		<bitfield name="CLIENT1" low="8"  high="15" type="uint"/>
+		<bitfield name="CLIENT2" low="16" high="23" type="uint"/>
 	</bitset>
 
 	<!-- Even though there is 1 MDP, length=2 to force dynamic offset usage -->
Signature · 3 lines
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project