dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/24] drm/bridge/sii8620: add Ultra HD modes support
       [not found] <CGME20170120073854eucas1p1f401f4de15eae3c0dc56aa47bef0a445@eucas1p1.samsung.com>
@ 2017-01-20  7:38 ` Andrzej Hajda
       [not found]   ` <CGME20170120073854eucas1p18dacd6261e9453a83c205bb0da7ecdd0@eucas1p1.samsung.com>
                     ` (23 more replies)
  0 siblings, 24 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Hi Archit,

This quite big patchset adds support for 4K Ultra HD modes in SiI8620 MHL bridge.
To support it full MHL3 protocol and its sub-protocols should be implemented.
Patchset contains also various fixes for bugs discovered during development.

Regards
Andrzej


Andrzej Hajda (24):
  drm/bridge/sii8620: simplify MHL3 mode setting
  drm/bridge/sii8620: add MHL3 mode check helper
  drm/bridge/sii8620: add reading device capability registers
  drm/bridge/sii8620: add continuations to messages
  drm/bridge/sii8620: initial support for eCBUS-S mode
  drm/bridge/mhl: add write burst related definitions
  drm/bridge/sii8620: add support for burst eMSC transmissions
  drm/bridge/sii8620: respond to feature requests
  drm/bridge/sii8620: fix peer device capabilities read code
  drm/bridge/sii8620: remove spare CBUS bring-up sequence
  drm/bridge/sii8620: fix MSC message removal
  drm/bridge/sii8620: fix initialization sequence for MHL2 receivers
  drm/bridge/sii8620: abstract out sink detection code
  drm/bridge/sii8620: set gen2 write burst before sending MSC command
  drm/bridge/sii8620: do not stop MHL output when TMDS input is stopped
  drm/bridge/sii8620: add delay during cbus reset
  drm/bridge/sii8620: split EDID read and write code
  drm/bridge/sii8620: fix disconnect sequence
  drm/bridge/sii8620: rewrite hdmi start sequence
  drm/bridge/sii8620: send EMSC features on request
  drm/bridge/sii8620: improve gen2 write burst IRQ routine
  drm/bridge/sii8620: add HSIC initialization code
  drm/bridge/sii8620: enable MHL3 mode if possible
  drm/bridge/sii8620: enable interlace modes

 drivers/gpu/drm/bridge/sil-sii8620.c | 917 ++++++++++++++++++++++++++++++-----
 drivers/gpu/drm/bridge/sil-sii8620.h |  50 +-
 include/drm/bridge/mhl.h             |  51 ++
 3 files changed, 868 insertions(+), 150 deletions(-)

-- 
2.7.4

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

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

* [PATCH 01/24] drm/bridge/sii8620: simplify MHL3 mode setting
       [not found]   ` <CGME20170120073854eucas1p18dacd6261e9453a83c205bb0da7ecdd0@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

It is not necessary to set REG_COC_CTL0, REG_MHL_COC_CTL1 registers.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index b2c267d..68cdf63 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -974,12 +974,8 @@ static void sii8620_set_mode(struct sii8620 *ctx, enum sii8620_mode mode)
 		);
 		break;
 	case CM_MHL3:
-		sii8620_write_seq_static(ctx,
-			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE,
-			REG_COC_CTL0, 0x40,
-			REG_MHL_COC_CTL1, 0x07
-		);
-		break;
+		sii8620_write(ctx, REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE);
+		return;
 	case CM_DISCONNECTED:
 		break;
 	default:
-- 
2.7.4

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

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

* [PATCH 02/24] drm/bridge/sii8620: add MHL3 mode check helper
       [not found]   ` <CGME20170120073855eucas1p18346c334bc74766a8af9ba76f3e8beb9@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL3 modes differs significantly from MHL1 mode, this helper will be used
frequently to clearly distinguish them.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 68cdf63..50af78f 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -227,6 +227,11 @@ static void sii8620_setbits(struct sii8620 *ctx, u16 addr, u8 mask, u8 val)
 	sii8620_write(ctx, addr, val);
 }
 
+static inline bool sii8620_is_mhl3(struct sii8620 *ctx)
+{
+	return ctx->mode >= CM_MHL3;
+}
+
 static void sii8620_mt_cleanup(struct sii8620 *ctx)
 {
 	struct sii8620_mt_msg *msg, *n;
@@ -724,7 +729,7 @@ static void sii8620_start_hdmi(struct sii8620 *ctx)
 
 static void sii8620_start_video(struct sii8620 *ctx)
 {
-	if (ctx->mode < CM_MHL3)
+	if (!sii8620_is_mhl3(ctx))
 		sii8620_stop_video(ctx);
 
 	switch (ctx->sink_type) {
@@ -838,7 +843,7 @@ static void sii8620_mhl_discover(struct sii8620 *ctx)
 
 static void sii8620_peer_specific_init(struct sii8620 *ctx)
 {
-	if (ctx->mode == CM_MHL3)
+	if (sii8620_is_mhl3(ctx))
 		sii8620_write_seq_static(ctx,
 			REG_SYS_CTRL1, BIT_SYS_CTRL1_BLOCK_DDC_BY_HPD,
 			REG_EMSCINTRMASK1,
-- 
2.7.4

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

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

* [PATCH 03/24] drm/bridge/sii8620: add reading device capability registers
       [not found]   ` <CGME20170120073855eucas1p1b8c6196a51ba9608cee9112dfa3c8f2c@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

This functionality is necessary to implement MHL3 modes.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 50af78f..75867c0 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -286,6 +286,12 @@ static void sii8620_mt_msc_cmd_send(struct sii8620 *ctx,
 		sii8620_write(ctx, REG_MSC_COMMAND_START,
 			      BIT_MSC_COMMAND_START_MSC_MSG);
 		break;
+	case MHL_READ_DEVCAP_REG:
+	case MHL_READ_XDEVCAP_REG:
+		sii8620_write(ctx, REG_MSC_CMD_OR_OFFSET, msg->reg[1]);
+		sii8620_write(ctx, REG_MSC_COMMAND_START,
+			      BIT_MSC_COMMAND_START_READ_DEVCAP);
+		break;
 	default:
 		dev_err(ctx->dev, "%s: command %#x not supported\n", __func__,
 			msg->reg[0]);
@@ -455,6 +461,35 @@ static void sii8620_mt_read_devcap(struct sii8620 *ctx, bool xdevcap)
 	msg->recv = sii8620_mt_read_devcap_recv;
 }
 
+static void sii8620_mt_read_devcap_reg_recv(struct sii8620 *ctx,
+		struct sii8620_mt_msg *msg)
+{
+	u8 reg = msg->reg[0] & 0x7f;
+
+	if (msg->reg[0] & 0x80)
+		ctx->xdevcap[reg] = msg->ret;
+	else
+		ctx->devcap[reg] = msg->ret;
+}
+
+static void sii8620_mt_read_devcap_reg(struct sii8620 *ctx, u8 reg)
+{
+	struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);
+
+	if (!msg)
+		return;
+
+	msg->reg[0] = (reg & 0x80) ? MHL_READ_XDEVCAP_REG : MHL_READ_DEVCAP_REG;
+	msg->reg[1] = reg;
+	msg->send = sii8620_mt_msc_cmd_send;
+	msg->recv = sii8620_mt_read_devcap_reg_recv;
+}
+
+static inline void sii8620_mt_read_xdevcap_reg(struct sii8620 *ctx, u8 reg)
+{
+	sii8620_mt_read_devcap_reg(ctx, reg | 0x80);
+}
+
 static void sii8620_fetch_edid(struct sii8620 *ctx)
 {
 	u8 lm_ddc, ddc_cmd, int3, cbus;
-- 
2.7.4

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

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

* [PATCH 04/24] drm/bridge/sii8620: add continuations to messages
       [not found]   ` <CGME20170120073855eucas1p1568d429ab0bfc41451183cca9f1c183a@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  2017-01-23  8:31       ` Archit Taneja
  0 siblings, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Due to asynchronous nature of MHL flow of execution is dispersed. Logical
continuation of some actions happens after response of peer, i.e in interrupt
handler. To simplify coding continuation mechanism has been added - it is now
possible to provide continuation callback, which will be called after peer
responds to given action.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 75867c0..cde0074 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -78,12 +78,15 @@ struct sii8620_mt_msg;
 typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
 				  struct sii8620_mt_msg *msg);
 
+typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
+
 struct sii8620_mt_msg {
 	struct list_head node;
 	u8 reg[4];
 	u8 ret;
 	sii8620_mt_msg_cb send;
 	sii8620_mt_msg_cb recv;
+	sii8620_cb continuation;
 };
 
 static const u8 sii8620_i2c_page[] = {
@@ -258,6 +261,8 @@ static void sii8620_mt_work(struct sii8620 *ctx)
 				       node);
 		if (msg->recv)
 			msg->recv(ctx, msg);
+		if (msg->continuation)
+			msg->continuation(ctx, msg->ret);
 		list_del(&msg->node);
 		kfree(msg);
 	}
@@ -310,6 +315,21 @@ static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx)
 	return msg;
 }
 
+static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont)
+{
+	struct sii8620_mt_msg *msg;
+
+	if (ctx->error)
+		return;
+
+	if (list_empty(&ctx->mt_queue)) {
+		ctx->error = -EINVAL;
+		return;
+	}
+	msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node);
+	msg->continuation = cont;
+}
+
 static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2)
 {
 	struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);
-- 
2.7.4

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

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

* [PATCH 05/24] drm/bridge/sii8620: initial support for eCBUS-S mode
       [not found]   ` <CGME20170120073856eucas1p1fa2a6007c5073f08c62f2c98aadb1726@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

The Single-ended eCBUS Mode (eCBUS-S) mode provides 60 Mb/s full-duplex
bidirectional traffic for three channels:
 - CBUS data (CBUS1 channel),
 - High-bandwidth MHL data (eMSC channel),
 - tunneling data (T-CBUS channel).
It is required to fully support MHL3 dongles.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 104 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/bridge/sil-sii8620.h |   5 ++
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index cde0074..9f9fd99 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -104,6 +104,7 @@ static void sii8620_fetch_edid(struct sii8620 *ctx);
 static void sii8620_set_upstream_edid(struct sii8620 *ctx);
 static void sii8620_enable_hpd(struct sii8620 *ctx);
 static void sii8620_mhl_disconnected(struct sii8620 *ctx);
+static void sii8620_disconnect(struct sii8620 *ctx);
 
 static int sii8620_clear_error(struct sii8620 *ctx)
 {
@@ -1016,13 +1017,44 @@ static void sii8620_mhl_init(struct sii8620 *ctx)
 	sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE), MHL_INT_RC_DCAP_CHG);
 }
 
+static void sii8620_emsc_enable(struct sii8620 *ctx)
+{
+	u8 reg;
+
+	sii8620_setbits(ctx, REG_GENCTL, BIT_GENCTL_EMSC_EN
+					 | BIT_GENCTL_CLR_EMSC_RFIFO
+					 | BIT_GENCTL_CLR_EMSC_XFIFO, ~0);
+	sii8620_setbits(ctx, REG_GENCTL, BIT_GENCTL_CLR_EMSC_RFIFO
+					 | BIT_GENCTL_CLR_EMSC_XFIFO, 0);
+	sii8620_setbits(ctx, REG_COMMECNT, BIT_COMMECNT_I2C_TO_EMSC_EN, ~0);
+	reg = sii8620_readb(ctx, REG_EMSCINTR);
+	sii8620_write(ctx, REG_EMSCINTR, reg);
+	sii8620_write(ctx, REG_EMSCINTRMASK, BIT_EMSCINTR_SPI_DVLD);
+}
+
+static int sii8620_wait_for_fsm_state(struct sii8620 *ctx, u8 state)
+{
+	int i;
+
+	for (i = 0; i < 10; ++i) {
+		u8 s = sii8620_readb(ctx, REG_COC_STAT_0);
+
+		if ((s & MSK_COC_STAT_0_FSM_STATE) == state)
+			return 0;
+		if (s & BIT_COC_STAT_0_PLL_LOCKED)
+			return -EBUSY;
+		usleep_range(4000, 6000);
+	}
+	return -ETIMEDOUT;
+}
+
 static void sii8620_set_mode(struct sii8620 *ctx, enum sii8620_mode mode)
 {
+	int ret;
+
 	if (ctx->mode == mode)
 		return;
 
-	ctx->mode = mode;
-
 	switch (mode) {
 	case CM_MHL1:
 		sii8620_write_seq_static(ctx,
@@ -1032,11 +1064,46 @@ static void sii8620_set_mode(struct sii8620 *ctx, enum sii8620_mode mode)
 				| BIT_DPD_OSC_EN,
 			REG_COC_INTR_MASK, 0
 		);
+		ctx->mode = mode;
 		break;
 	case CM_MHL3:
 		sii8620_write(ctx, REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE);
+		ctx->mode = mode;
+		return;
+	case CM_ECBUS_S:
+		sii8620_emsc_enable(ctx);
+		sii8620_write_seq_static(ctx,
+			REG_TTXSPINUMS, 4,
+			REG_TRXSPINUMS, 4,
+			REG_TTXHSICNUMS, 0x14,
+			REG_TRXHSICNUMS, 0x14,
+			REG_TTXTOTNUMS, 0x18,
+			REG_TRXTOTNUMS, 0x18,
+			REG_PWD_SRST, BIT_PWD_SRST_COC_DOC_RST
+				      | BIT_PWD_SRST_CBUS_RST_SW_EN,
+			REG_MHL_COC_CTL1, 0xbd,
+			REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST_SW_EN,
+			REG_COC_CTLB, 0x01,
+			REG_COC_CTL0, 0x5c,
+			REG_COC_CTL14, 0x03,
+			REG_COC_CTL15, 0x80,
+			REG_MHL_DP_CTL6, BIT_MHL_DP_CTL6_DP_TAP1_SGN
+					 | BIT_MHL_DP_CTL6_DP_TAP1_EN
+					 | BIT_MHL_DP_CTL6_DT_PREDRV_FEEDCAP_EN,
+			REG_MHL_DP_CTL8, 0x03
+		);
+		ret = sii8620_wait_for_fsm_state(ctx, 0x03);
+		sii8620_write_seq_static(ctx,
+			REG_COC_CTL14, 0x00,
+			REG_COC_CTL15, 0x80
+		);
+		if (!ret)
+			sii8620_write(ctx, REG_CBUS3_CNVT, 0x85);
+		else
+			sii8620_disconnect(ctx);
 		return;
 	case CM_DISCONNECTED:
+		ctx->mode = mode;
 		break;
 	default:
 		dev_err(ctx->dev, "%s mode %d not supported\n", __func__, mode);
@@ -1229,12 +1296,45 @@ static void sii8620_msc_mr_write_stat(struct sii8620 *ctx)
 		sii8620_status_changed_path(ctx);
 }
 
+static void sii8620_ecbus_up(struct sii8620 *ctx, int ret)
+{
+	if (ret < 0)
+		return;
+
+	sii8620_set_mode(ctx, CM_ECBUS_S);
+}
+
+static void sii8620_got_ecbus_speed(struct sii8620 *ctx, int ret)
+{
+	if (ret < 0)
+		return;
+
+	sii8620_mt_write_stat(ctx, MHL_XDS_REG(CURR_ECBUS_MODE),
+			      MHL_XDS_ECBUS_S | MHL_XDS_SLOT_MODE_8BIT);
+	sii8620_mt_rap(ctx, MHL_RAP_CBUS_MODE_UP);
+	sii8620_mt_set_cont(ctx, sii8620_ecbus_up);
+}
+
 static void sii8620_msc_mr_set_int(struct sii8620 *ctx)
 {
 	u8 ints[MHL_INT_SIZE];
 
 	sii8620_read_buf(ctx, REG_MHL_INT_0, ints, MHL_INT_SIZE);
 	sii8620_write_buf(ctx, REG_MHL_INT_0, ints, MHL_INT_SIZE);
+
+	if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_DCAP_CHG) {
+		switch (ctx->mode) {
+		case CM_MHL3:
+			sii8620_mt_read_xdevcap_reg(ctx, MHL_XDC_ECBUS_SPEEDS);
+			sii8620_mt_set_cont(ctx, sii8620_got_ecbus_speed);
+			break;
+		case CM_ECBUS_S:
+			sii8620_mt_read_devcap(ctx, true);
+			break;
+		default:
+			break;
+		}
+	}
 }
 
 static struct sii8620_mt_msg *sii8620_msc_msg_first(struct sii8620 *ctx)
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index 6ff616a..3ee4e7e 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -841,6 +841,8 @@
 #define MSK_MHL_DP_CTL7_DT_DRV_VBIAS_CASCTL	0xf0
 #define MSK_MHL_DP_CTL7_DT_DRV_IREF_CTL		0x0f
 
+#define REG_MHL_DP_CTL8				0x0352
+
 /* Tx Zone Ctl1, default value: 0x00 */
 #define REG_TX_ZONE_CTL1			0x0361
 #define VAL_TX_ZONE_CTL1_TX_ZONE_CTRL_MODE	0x08
@@ -1088,6 +1090,9 @@
 
 /* CoC Status, default value: 0x00 */
 #define REG_COC_STAT_0				0x0700
+#define BIT_COC_STAT_0_PLL_LOCKED		BIT(7)
+#define MSK_COC_STAT_0_FSM_STATE		0x0f
+
 #define REG_COC_STAT_1				0x0701
 #define REG_COC_STAT_2				0x0702
 #define REG_COC_STAT_3				0x0703
-- 
2.7.4

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

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

* [PATCH 06/24] drm/bridge/mhl: add write burst related definitions
       [not found]   ` <CGME20170120073856eucas1p1124fd039bd23e0add19dced61a55852a@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Burst transmissions are required in MHL3 modes.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 include/drm/bridge/mhl.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/include/drm/bridge/mhl.h b/include/drm/bridge/mhl.h
index 3629b27..71d922f 100644
--- a/include/drm/bridge/mhl.h
+++ b/include/drm/bridge/mhl.h
@@ -288,4 +288,55 @@ enum {
 /* Unsupported/unrecognized key code */
 #define MHL_UCPE_STATUS_INEFFECTIVE_KEY_CODE	0x01
 
+enum mhl_burst_id {
+	MHL_BURST_ID_3D_VIC = 0x10,
+	MHL_BURST_ID_3D_DTD = 0x11,
+	MHL_BURST_ID_HEV_VIC = 0x20,
+	MHL_BURST_ID_HEV_DTDA = 0x21,
+	MHL_BURST_ID_HEV_DTDB = 0x22,
+	MHL_BURST_ID_VC_ASSIGN = 0x38,
+	MHL_BURST_ID_VC_CONFIRM = 0x39,
+	MHL_BURST_ID_AUD_DELAY = 0x40,
+	MHL_BURST_ID_ADT_BURSTID = 0x41,
+	MHL_BURST_ID_BIST_SETUP = 0x51,
+	MHL_BURST_ID_BIST_RETURN_STAT = 0x52,
+	MHL_BURST_ID_EMSC_SUPPORT = 0x61,
+	MHL_BURST_ID_HID_PAYLOAD = 0x62,
+	MHL_BURST_ID_BLK_RCV_BUFFER_INFO = 0x63,
+	MHL_BURST_ID_BITS_PER_PIXEL_FMT = 0x64,
+};
+
+struct mhl_burst_blk_rcv_buffer_info {
+	__be16 id;
+	__le16 size;
+} __packed;
+
+struct mhl3_burst_header {
+	__be16 id;
+	u8 checksum;
+	u8 total_entries;
+	u8 sequence_index;
+} __packed;
+
+struct mhl_burst_bits_per_pixel_fmt {
+	struct mhl3_burst_header hdr;
+	u8 num_entries;
+	struct {
+		u8 stream_id;
+		u8 pixel_format;
+	} __packed desc[0];
+} __packed;
+
+struct mhl_burst_emsc_support {
+	struct mhl3_burst_header hdr;
+	u8 num_entries;
+	__be16 burst_id[0];
+} __packed;
+
+struct mhl_burst_audio_descr {
+	struct mhl3_burst_header hdr;
+	u8 flags;
+	u8 short_desc[9];
+} __packed;
+
 #endif /* __MHL_H__ */
-- 
2.7.4

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

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

* [PATCH 07/24] drm/bridge/sii8620: add support for burst eMSC transmissions
       [not found]   ` <CGME20170120073857eucas1p2669acdcb12a64294bccebece4990fb5c@eucas1p2.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  2017-01-23  8:20       ` Archit Taneja
  0 siblings, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Burst transmissions are used in MHL3 mode negotiation.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 196 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/bridge/sil-sii8620.h |   4 +
 2 files changed, 198 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 9f9fd99..744e685 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -9,6 +9,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <asm/unaligned.h>
+
 #include <drm/bridge/mhl.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
@@ -28,7 +30,8 @@
 
 #include "sil-sii8620.h"
 
-#define VAL_RX_HDMI_CTRL2_DEFVAL	VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
+#define SII8620_BURST_BUF_LEN 288
+#define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
 
 enum sii8620_mode {
 	CM_DISCONNECTED,
@@ -71,6 +74,15 @@ struct sii8620 {
 	unsigned int gen2_write_burst:1;
 	enum sii8620_mt_state mt_state;
 	struct list_head mt_queue;
+	struct {
+		int r_size;
+		int r_count;
+		int rx_ack;
+		int rx_count;
+		u8 rx_buf[32];
+		int tx_count;
+		u8 tx_buf[32];
+	} burst;
 };
 
 struct sii8620_mt_msg;
@@ -511,6 +523,134 @@ static inline void sii8620_mt_read_xdevcap_reg(struct sii8620 *ctx, u8 reg)
 	sii8620_mt_read_devcap_reg(ctx, reg | 0x80);
 }
 
+static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)
+{
+	u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];
+	int size = len + 2;
+
+	if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
+		dev_err(ctx->dev, "TX-BLK buffer exhausted\n");
+		ctx->error = -EINVAL;
+		return NULL;
+	}
+
+	ctx->burst.tx_count += size;
+	buf[1] = len;
+
+	return buf + 2;
+}
+
+static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)
+{
+	u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];
+	int size = len + 1;
+
+	if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
+		dev_err(ctx->dev, "RX-BLK buffer exhausted\n");
+		ctx->error = -EINVAL;
+		return NULL;
+	}
+
+	ctx->burst.rx_count += size;
+	buf[0] = len;
+
+	return buf + 1;
+}
+
+static void sii8620_burst_send(struct sii8620 *ctx)
+{
+	int tx_left = ctx->burst.tx_count;
+	u8 *d = ctx->burst.tx_buf;
+
+	while (tx_left > 0) {
+		int len = d[1] + 2;
+
+		if (ctx->burst.r_count + len > ctx->burst.r_size)
+			break;
+		d[0] = min(ctx->burst.rx_ack, 255);
+		ctx->burst.rx_ack -= d[0];
+		sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, d, len);
+		ctx->burst.r_count += len;
+		tx_left -= len;
+		d += len;
+	}
+
+	ctx->burst.tx_count = tx_left;
+
+	while (ctx->burst.rx_ack > 0) {
+		u8 b[2] = { min(ctx->burst.rx_ack, 255), 0 };
+
+		if (ctx->burst.r_count + 2 > ctx->burst.r_size)
+			break;
+		ctx->burst.rx_ack -= b[0];
+		sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, b, 2);
+		ctx->burst.r_count += 2;
+	}
+}
+
+static void sii8620_burst_receive(struct sii8620 *ctx)
+{
+	u8 buf[3], *d;
+	int count;
+
+	sii8620_read_buf(ctx, REG_EMSCRFIFOBCNTL, buf, 2);
+	count = get_unaligned_le16(buf);
+	while (count > 0) {
+		int len = min(count, 3);
+
+		sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, buf, len);
+		count -= len;
+		ctx->burst.rx_ack += len - 1;
+		ctx->burst.r_count -= buf[1];
+		if (ctx->burst.r_count < 0)
+			ctx->burst.r_count = 0;
+
+		if (len < 3 || !buf[2])
+			continue;
+
+		len = buf[2];
+		d = sii8620_burst_get_rx_buf(ctx, len);
+		if (!d)
+			continue;
+		sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, d, len);
+		count -= len;
+		ctx->burst.rx_ack += len;
+	}
+}
+
+static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
+{
+	struct mhl_burst_blk_rcv_buffer_info *d =
+		sii8620_burst_get_tx_buf(ctx, sizeof(*d));
+	if (!d)
+		return;
+
+	d->id = cpu_to_be16(MHL_BURST_ID_BLK_RCV_BUFFER_INFO);
+	d->size = cpu_to_le16(size);
+}
+
+static void sii8620_burst_rx_all(struct sii8620 *ctx)
+{
+	u8 *d = ctx->burst.rx_buf;
+	int count = ctx->burst.rx_count;
+
+	while (count-- > 0) {
+		int len = *d++;
+		int id = get_unaligned_be16(&d[0]);
+
+		switch (id) {
+		case MHL_BURST_ID_BLK_RCV_BUFFER_INFO:
+			ctx->burst.r_size = get_unaligned_le16(&d[2]);
+			break;
+		default:
+			break;
+		}
+		count -= len;
+		d += len;
+	}
+	ctx->burst.rx_count = 0;
+}
+
 static void sii8620_fetch_edid(struct sii8620 *ctx)
 {
 	u8 lm_ddc, ddc_cmd, int3, cbus;
@@ -1041,7 +1181,7 @@ static int sii8620_wait_for_fsm_state(struct sii8620 *ctx, u8 state)
 
 		if ((s & MSK_COC_STAT_0_FSM_STATE) == state)
 			return 0;
-		if (s & BIT_COC_STAT_0_PLL_LOCKED)
+		if (!(s & BIT_COC_STAT_0_PLL_LOCKED))
 			return -EBUSY;
 		usleep_range(4000, 6000);
 	}
@@ -1417,6 +1557,19 @@ static void sii8620_irq_coc(struct sii8620 *ctx)
 {
 	u8 stat = sii8620_readb(ctx, REG_COC_INTR);
 
+	if (stat & BIT_COC_CALIBRATION_DONE) {
+		u8 cstat = sii8620_readb(ctx, REG_COC_STAT_0);
+
+		cstat &= BIT_COC_STAT_0_PLL_LOCKED | MSK_COC_STAT_0_FSM_STATE;
+		if (cstat == (BIT_COC_STAT_0_PLL_LOCKED | 0x02)) {
+			sii8620_write_seq_static(ctx,
+				REG_COC_CTLB, 0,
+				REG_TRXINTMH, BIT_TDM_INTR_SYNC_DATA
+					      | BIT_TDM_INTR_SYNC_WAIT
+			);
+		}
+	}
+
 	sii8620_write(ctx, REG_COC_INTR, stat);
 }
 
@@ -1507,6 +1660,41 @@ static void sii8620_irq_infr(struct sii8620 *ctx)
 		sii8620_start_video(ctx);
 }
 
+static void sii8620_irq_tdm(struct sii8620 *ctx)
+{
+	u8 stat = sii8620_readb(ctx, REG_TRXINTH);
+	u8 tdm = sii8620_readb(ctx, REG_TRXSTA2);
+
+	if ((tdm & MSK_TDM_SYNCHRONIZED) == VAL_TDM_SYNCHRONIZED) {
+		ctx->mode = CM_ECBUS_S;
+		ctx->burst.rx_ack = 0;
+		ctx->burst.r_size = SII8620_BURST_BUF_LEN;
+		sii8620_burst_tx_rbuf_info(ctx, SII8620_BURST_BUF_LEN);
+		sii8620_mt_read_devcap(ctx, true);
+	} else {
+		sii8620_write_seq_static(ctx,
+			REG_MHL_PLL_CTL2, 0,
+			REG_MHL_PLL_CTL2, BIT_MHL_PLL_CTL2_CLKDETECT_EN
+		);
+	}
+
+	sii8620_write(ctx, REG_TRXINTH, stat);
+}
+
+static void sii8620_irq_block(struct sii8620 *ctx)
+{
+	u8 stat = sii8620_readb(ctx, REG_EMSCINTR);
+
+	if (stat & BIT_EMSCINTR_SPI_DVLD) {
+		u8 bstat = sii8620_readb(ctx, REG_SPIBURSTSTAT);
+
+		if (bstat & BIT_SPIBURSTSTAT_EMSC_NORMAL_MODE)
+			sii8620_burst_receive(ctx);
+	}
+
+	sii8620_write(ctx, REG_EMSCINTR, stat);
+}
+
 /* endian agnostic, non-volatile version of test_bit */
 static bool sii8620_test_bit(unsigned int nr, const u8 *addr)
 {
@@ -1522,8 +1710,10 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
 		{ BIT_FAST_INTR_STAT_DISC, sii8620_irq_disc },
 		{ BIT_FAST_INTR_STAT_G2WB, sii8620_irq_g2wb },
 		{ BIT_FAST_INTR_STAT_COC, sii8620_irq_coc },
+		{ BIT_FAST_INTR_STAT_TDM, sii8620_irq_tdm },
 		{ BIT_FAST_INTR_STAT_MSC, sii8620_irq_msc },
 		{ BIT_FAST_INTR_STAT_MERR, sii8620_irq_merr },
+		{ BIT_FAST_INTR_STAT_BLOCK, sii8620_irq_block },
 		{ BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid },
 		{ BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt },
 		{ BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr },
@@ -1539,7 +1729,9 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
 		if (sii8620_test_bit(irq_vec[i].bit, stats))
 			irq_vec[i].handler(ctx);
 
+	sii8620_burst_rx_all(ctx);
 	sii8620_mt_work(ctx);
+	sii8620_burst_send(ctx);
 
 	ret = sii8620_clear_error(ctx);
 	if (ret) {
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index 3ee4e7e..f7bfbc3 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -403,12 +403,16 @@
 
 /* TDM RX Status 2nd, default value: 0x00 */
 #define REG_TRXSTA2				0x015c
+#define MSK_TDM_SYNCHRONIZED			0xC0
+#define VAL_TDM_SYNCHRONIZED			0x80
 
 /* TDM RX INT Low, default value: 0x00 */
 #define REG_TRXINTL				0x0163
 
 /* TDM RX INT High, default value: 0x00 */
 #define REG_TRXINTH				0x0164
+#define BIT_TDM_INTR_SYNC_DATA			BIT(0)
+#define BIT_TDM_INTR_SYNC_WAIT			BIT(1)
 
 /* TDM RX INTMASK High, default value: 0x00 */
 #define REG_TRXINTMH				0x0166
-- 
2.7.4

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

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

* [PATCH 08/24] drm/bridge/sii8620: respond to feature requests
       [not found]   ` <CGME20170120073857eucas1p14c07f158f99c6d89d7d879c28afbeafc@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL3 protocol requires device to respond to feature request from peer.
This minimal answer fulfills the requirement and allows to continue
negotiation.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 744e685..3842226 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1475,6 +1475,10 @@ static void sii8620_msc_mr_set_int(struct sii8620 *ctx)
 			break;
 		}
 	}
+	if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_REQ) {
+		sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE),
+				   MHL_INT_RC_FEAT_COMPLETE);
+	}
 }
 
 static struct sii8620_mt_msg *sii8620_msc_msg_first(struct sii8620 *ctx)
-- 
2.7.4

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

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

* [PATCH 09/24] drm/bridge/sii8620: fix peer device capabilities read code
       [not found]   ` <CGME20170120073857eucas1p1776cb0ca12d233450c81cbeab053f729@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Peer capabilities should be read differently depending on protocol version.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 3842226..be953f3 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1412,7 +1412,8 @@ static void sii8620_status_changed_path(struct sii8620 *ctx)
 		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
 				      MHL_DST_LM_CLK_MODE_NORMAL
 				      | MHL_DST_LM_PATH_ENABLED);
-		sii8620_mt_read_devcap(ctx, false);
+		if (!sii8620_is_mhl3(ctx))
+			sii8620_mt_read_devcap(ctx, false);
 	} else {
 		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
 				      MHL_DST_LM_CLK_MODE_NORMAL);
@@ -1664,6 +1665,14 @@ static void sii8620_irq_infr(struct sii8620 *ctx)
 		sii8620_start_video(ctx);
 }
 
+static void sii8620_got_xdevcap(struct sii8620 *ctx, int ret)
+{
+	if (ret < 0)
+		return;
+
+	sii8620_mt_read_devcap(ctx, false);
+}
+
 static void sii8620_irq_tdm(struct sii8620 *ctx)
 {
 	u8 stat = sii8620_readb(ctx, REG_TRXINTH);
@@ -1675,6 +1684,7 @@ static void sii8620_irq_tdm(struct sii8620 *ctx)
 		ctx->burst.r_size = SII8620_BURST_BUF_LEN;
 		sii8620_burst_tx_rbuf_info(ctx, SII8620_BURST_BUF_LEN);
 		sii8620_mt_read_devcap(ctx, true);
+		sii8620_mt_set_cont(ctx, sii8620_got_xdevcap);
 	} else {
 		sii8620_write_seq_static(ctx,
 			REG_MHL_PLL_CTL2, 0,
-- 
2.7.4

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

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

* [PATCH 10/24] drm/bridge/sii8620: remove spare CBUS bring-up sequence
       [not found]   ` <CGME20170120073857eucas1p18fa1efe180224d8bba37ec598d09b9ac@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

In case of MHL3 CBUS is bring-up already in sii8620_got_ecbus_speed.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index be953f3..fb69353 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -453,10 +453,6 @@ static void sii8620_mr_xdevcap(struct sii8620 *ctx)
 {
 	sii8620_read_buf(ctx, REG_EDID_FIFO_RD_DATA, ctx->xdevcap,
 			 MHL_XDC_SIZE);
-
-	sii8620_mt_write_stat(ctx, MHL_XDS_REG(CURR_ECBUS_MODE),
-			      MHL_XDS_ECBUS_S | MHL_XDS_SLOT_MODE_8BIT);
-	sii8620_mt_rap(ctx, MHL_RAP_CBUS_MODE_UP);
 }
 
 static void sii8620_mt_read_devcap_recv(struct sii8620 *ctx,
-- 
2.7.4

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

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

* [PATCH 11/24] drm/bridge/sii8620: fix MSC message removal
       [not found]   ` <CGME20170120073858eucas1p1f833db10ddca4a46be42f7b879063fd1@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Messages queue can be cleaned up by message callbacks, to avoid repeated
removal of current message it should be removed from the queue before calling
these callbacks.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index fb69353..a50ade6 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -272,11 +272,11 @@ static void sii8620_mt_work(struct sii8620 *ctx)
 		ctx->mt_state = MT_STATE_READY;
 		msg = list_first_entry(&ctx->mt_queue, struct sii8620_mt_msg,
 				       node);
+		list_del(&msg->node);
 		if (msg->recv)
 			msg->recv(ctx, msg);
 		if (msg->continuation)
 			msg->continuation(ctx, msg->ret);
-		list_del(&msg->node);
 		kfree(msg);
 	}
 
-- 
2.7.4

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

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

* [PATCH 12/24] drm/bridge/sii8620: fix initialization sequence for MHL2 receivers
       [not found]   ` <CGME20170120073858eucas1p15c1f5ddb032763d29ad045d1416a4f10@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL2 receiver require disabling transmitter on initialization.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index a50ade6..7d28690 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -880,12 +880,11 @@ static void sii8620_stop_video(struct sii8620 *ctx)
 			| BIT_TPI_SC_TPI_AV_MUTE;
 		break;
 	case SINK_HDMI:
+	default:
 		val = BIT_TPI_SC_REG_TMDS_OE_POWER_DOWN
 			| BIT_TPI_SC_TPI_AV_MUTE
 			| BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI;
 		break;
-	default:
-		return;
 	}
 
 	sii8620_write(ctx, REG_TPI_SC, val);
-- 
2.7.4

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

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

* [PATCH 13/24] drm/bridge/sii8620: abstract out sink detection code
       [not found]   ` <CGME20170120073859eucas1p2c241656291e20876c3e36133ab8f145e@eucas1p2.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL1 and MHL3 have different initialization paths. To make both protocols
happy sink detection is put into continuation after link mode enablement.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 7d28690..5b879ff 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -402,7 +402,7 @@ static void sii8620_update_array(u8 *dst, u8 *src, int count)
 	}
 }
 
-static void sii8620_mr_devcap(struct sii8620 *ctx)
+static void sii8620_sink_detected(struct sii8620 *ctx, int ret)
 {
 	static const char * const sink_str[] = {
 		[SINK_NONE] = "NONE",
@@ -410,23 +410,10 @@ static void sii8620_mr_devcap(struct sii8620 *ctx)
 		[SINK_DVI] = "DVI"
 	};
 
-	u8 dcap[MHL_DCAP_SIZE];
 	char sink_name[20];
 	struct device *dev = ctx->dev;
 
-	sii8620_read_buf(ctx, REG_EDID_FIFO_RD_DATA, dcap, MHL_DCAP_SIZE);
-	if (ctx->error < 0)
-		return;
-
-	dev_info(dev, "dcap: %*ph\n", MHL_DCAP_SIZE, dcap);
-	dev_info(dev, "detected dongle MHL %d.%d, ChipID %02x%02x:%02x%02x\n",
-		 dcap[MHL_DCAP_MHL_VERSION] / 16,
-		 dcap[MHL_DCAP_MHL_VERSION] % 16, dcap[MHL_DCAP_ADOPTER_ID_H],
-		 dcap[MHL_DCAP_ADOPTER_ID_L], dcap[MHL_DCAP_DEVICE_ID_H],
-		 dcap[MHL_DCAP_DEVICE_ID_L]);
-	sii8620_update_array(ctx->devcap, dcap, MHL_DCAP_SIZE);
-
-	if (!(dcap[MHL_DCAP_CAT] & MHL_DCAP_CAT_SINK))
+	if (ret < 0)
 		return;
 
 	sii8620_fetch_edid(ctx);
@@ -449,6 +436,22 @@ static void sii8620_mr_devcap(struct sii8620 *ctx)
 	sii8620_enable_hpd(ctx);
 }
 
+static void sii8620_mr_devcap(struct sii8620 *ctx)
+{
+	u8 dcap[MHL_DCAP_SIZE];
+	struct device *dev = ctx->dev;
+
+	sii8620_read_buf(ctx, REG_EDID_FIFO_RD_DATA, dcap, MHL_DCAP_SIZE);
+	if (ctx->error < 0)
+		return;
+
+	dev_info(dev, "detected dongle MHL %d.%d, ChipID %02x%02x:%02x%02x\n",
+		dcap[MHL_DCAP_MHL_VERSION] / 16, dcap[MHL_DCAP_MHL_VERSION] % 16,
+		dcap[MHL_DCAP_ADOPTER_ID_H], dcap[MHL_DCAP_ADOPTER_ID_L],
+		dcap[MHL_DCAP_DEVICE_ID_H], dcap[MHL_DCAP_DEVICE_ID_L]);
+	sii8620_update_array(ctx->devcap, dcap, MHL_DCAP_SIZE);
+}
+
 static void sii8620_mr_xdevcap(struct sii8620 *ctx)
 {
 	sii8620_read_buf(ctx, REG_EDID_FIFO_RD_DATA, ctx->xdevcap,
@@ -1409,6 +1412,7 @@ static void sii8620_status_changed_path(struct sii8620 *ctx)
 				      | MHL_DST_LM_PATH_ENABLED);
 		if (!sii8620_is_mhl3(ctx))
 			sii8620_mt_read_devcap(ctx, false);
+		sii8620_mt_set_cont(ctx, sii8620_sink_detected);
 	} else {
 		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
 				      MHL_DST_LM_CLK_MODE_NORMAL);
-- 
2.7.4

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

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

* [PATCH 14/24] drm/bridge/sii8620: set gen2 write burst before sending MSC command
       [not found]   ` <CGME20170120073859eucas1p11cc6d9d02494c47b0e3a671378552064@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Write burst should be enabled for MHL_INT_RC_FEAT_REQ and disabled for
other commands. The patch moves functions up and adds delay setting
for MHL3 burst mode.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 88 ++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 5b879ff..653187c 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -289,9 +289,59 @@ static void sii8620_mt_work(struct sii8620 *ctx)
 		msg->send(ctx, msg);
 }
 
+static void sii8620_enable_gen2_write_burst(struct sii8620 *ctx)
+{
+	u8 ctrl = BIT_MDT_RCV_CTRL_MDT_RCV_EN;
+
+	if (ctx->gen2_write_burst)
+		return;
+
+	if (ctx->mode >= CM_MHL1)
+		ctrl |= BIT_MDT_RCV_CTRL_MDT_DELAY_RCV_EN;
+
+	sii8620_write_seq(ctx,
+		REG_MDT_RCV_TIMEOUT, 100,
+		REG_MDT_RCV_CTRL, ctrl
+	);
+	ctx->gen2_write_burst = 1;
+}
+
+static void sii8620_disable_gen2_write_burst(struct sii8620 *ctx)
+{
+	if (!ctx->gen2_write_burst)
+		return;
+
+	sii8620_write_seq_static(ctx,
+		REG_MDT_XMIT_CTRL, 0,
+		REG_MDT_RCV_CTRL, 0
+	);
+	ctx->gen2_write_burst = 0;
+}
+
+static void sii8620_start_gen2_write_burst(struct sii8620 *ctx)
+{
+	sii8620_write_seq_static(ctx,
+		REG_MDT_INT_1_MASK, BIT_MDT_RCV_TIMEOUT
+			| BIT_MDT_RCV_SM_ABORT_PKT_RCVD | BIT_MDT_RCV_SM_ERROR
+			| BIT_MDT_XMIT_TIMEOUT | BIT_MDT_XMIT_SM_ABORT_PKT_RCVD
+			| BIT_MDT_XMIT_SM_ERROR,
+		REG_MDT_INT_0_MASK, BIT_MDT_XFIFO_EMPTY
+			| BIT_MDT_IDLE_AFTER_HAWB_DISABLE
+			| BIT_MDT_RFIFO_DATA_RDY
+	);
+	sii8620_enable_gen2_write_burst(ctx);
+}
+
 static void sii8620_mt_msc_cmd_send(struct sii8620 *ctx,
 				    struct sii8620_mt_msg *msg)
 {
+	if (msg->reg[0] == MHL_SET_INT &&
+	    msg->reg[1] == MHL_INT_REG(RCHANGE) &&
+	    msg->reg[2] == MHL_INT_RC_FEAT_REQ)
+		sii8620_enable_gen2_write_burst(ctx);
+	else
+		sii8620_disable_gen2_write_burst(ctx);
+
 	switch (msg->reg[0]) {
 	case MHL_WRITE_STAT:
 	case MHL_SET_INT:
@@ -956,44 +1006,6 @@ static void sii8620_enable_hpd(struct sii8620 *ctx)
 	);
 }
 
-static void sii8620_enable_gen2_write_burst(struct sii8620 *ctx)
-{
-	if (ctx->gen2_write_burst)
-		return;
-
-	sii8620_write_seq_static(ctx,
-		REG_MDT_RCV_TIMEOUT, 100,
-		REG_MDT_RCV_CTRL, BIT_MDT_RCV_CTRL_MDT_RCV_EN
-	);
-	ctx->gen2_write_burst = 1;
-}
-
-static void sii8620_disable_gen2_write_burst(struct sii8620 *ctx)
-{
-	if (!ctx->gen2_write_burst)
-		return;
-
-	sii8620_write_seq_static(ctx,
-		REG_MDT_XMIT_CTRL, 0,
-		REG_MDT_RCV_CTRL, 0
-	);
-	ctx->gen2_write_burst = 0;
-}
-
-static void sii8620_start_gen2_write_burst(struct sii8620 *ctx)
-{
-	sii8620_write_seq_static(ctx,
-		REG_MDT_INT_1_MASK, BIT_MDT_RCV_TIMEOUT
-			| BIT_MDT_RCV_SM_ABORT_PKT_RCVD | BIT_MDT_RCV_SM_ERROR
-			| BIT_MDT_XMIT_TIMEOUT | BIT_MDT_XMIT_SM_ABORT_PKT_RCVD
-			| BIT_MDT_XMIT_SM_ERROR,
-		REG_MDT_INT_0_MASK, BIT_MDT_XFIFO_EMPTY
-			| BIT_MDT_IDLE_AFTER_HAWB_DISABLE
-			| BIT_MDT_RFIFO_DATA_RDY
-	);
-	sii8620_enable_gen2_write_burst(ctx);
-}
-
 static void sii8620_mhl_discover(struct sii8620 *ctx)
 {
 	sii8620_write_seq_static(ctx,
-- 
2.7.4

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

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

* [PATCH 15/24] drm/bridge/sii8620: do not stop MHL output when TMDS input is stopped
       [not found]   ` <CGME20170120073859eucas1p1605dfb90b8357a12339b9a6661ec7d7d@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Stopping output causes full re-detection of the sink and slows down the process.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 653187c..e84cda0 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1614,17 +1614,6 @@ static void sii8620_scdt_high(struct sii8620 *ctx)
 	);
 }
 
-static void sii8620_scdt_low(struct sii8620 *ctx)
-{
-	sii8620_write(ctx, REG_TMDS_CSTAT_P3,
-		      BIT_TMDS_CSTAT_P3_SCDT_CLR_AVI_DIS |
-		      BIT_TMDS_CSTAT_P3_CLR_AVI);
-
-	sii8620_stop_video(ctx);
-
-	sii8620_write(ctx, REG_INTR8_MASK, 0);
-}
-
 static void sii8620_irq_scdt(struct sii8620 *ctx)
 {
 	u8 stat = sii8620_readb(ctx, REG_INTR5);
@@ -1634,8 +1623,6 @@ static void sii8620_irq_scdt(struct sii8620 *ctx)
 
 		if (cstat & BIT_TMDS_CSTAT_P3_SCDT)
 			sii8620_scdt_high(ctx);
-		else
-			sii8620_scdt_low(ctx);
 	}
 
 	sii8620_write(ctx, REG_INTR5, stat);
-- 
2.7.4

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

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

* [PATCH 16/24] drm/bridge/sii8620: add delay during cbus reset
       [not found]   ` <CGME20170120073900eucas1p23f98ec5ce9d624e85611a77f60d65402@eucas1p2.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Without delay CBUS sometimes was not reset properly.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index e84cda0..6ef1a4d 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -891,11 +891,10 @@ static void sii8620_hw_reset(struct sii8620 *ctx)
 
 static void sii8620_cbus_reset(struct sii8620 *ctx)
 {
-	sii8620_write_seq_static(ctx,
-		REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST
-			| BIT_PWD_SRST_CBUS_RST_SW_EN,
-		REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST_SW_EN
-	);
+	sii8620_write(ctx, REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST
+		      | BIT_PWD_SRST_CBUS_RST_SW_EN);
+	usleep_range(10000, 20000);
+	sii8620_write(ctx, REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST_SW_EN);
 }
 
 static void sii8620_set_auto_zone(struct sii8620 *ctx)
-- 
2.7.4

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

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

* [PATCH 17/24] drm/bridge/sii8620: split EDID read and write code
       [not found]   ` <CGME20170120073900eucas1p15da0726bf6e9bcdf0d9a7bbfea670918@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  2017-01-24 10:31       ` Archit Taneja
  0 siblings, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL3 requires that after reading EDID from the sink source should ask
peer for features. To make both protocols happy the patch splits the code
accordingly.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 6ef1a4d..d0e6dc3 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -482,6 +482,13 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret)
 
 	dev_info(dev, "detected sink(type: %s): %s\n",
 		 sink_str[ctx->sink_type], sink_name);
+}
+
+static void sii8620_edid_read(struct sii8620 *ctx, int ret)
+{
+	if (ret < 0)
+		return;
+
 	sii8620_set_upstream_edid(ctx);
 	sii8620_enable_hpd(ctx);
 }
@@ -787,12 +794,12 @@ static void sii8620_fetch_edid(struct sii8620 *ctx)
 				edid = new_edid;
 			}
 		}
-
-		if (fetched + FETCH_SIZE == edid_len)
-			sii8620_write(ctx, REG_INTR3, int3);
 	}
 
-	sii8620_write(ctx, REG_LM_DDC, lm_ddc);
+	sii8620_write_seq(ctx,
+		REG_INTR3_MASK, BIT_DDC_CMD_DONE,
+		REG_LM_DDC, lm_ddc
+	);
 
 end:
 	kfree(ctx->edid);
@@ -1706,6 +1713,21 @@ static void sii8620_irq_block(struct sii8620 *ctx)
 	sii8620_write(ctx, REG_EMSCINTR, stat);
 }
 
+static void sii8620_irq_ddc(struct sii8620 *ctx)
+{
+	u8 stat = sii8620_readb(ctx, REG_INTR3);
+
+	if (stat & BIT_DDC_CMD_DONE) {
+		sii8620_write(ctx, REG_INTR3_MASK, 0);
+		if (sii8620_is_mhl3(ctx))
+			sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE),
+					   MHL_INT_RC_FEAT_REQ);
+		else
+			sii8620_edid_read(ctx, 0);
+	}
+	sii8620_write(ctx, REG_INTR3, stat);
+}
+
 /* endian agnostic, non-volatile version of test_bit */
 static bool sii8620_test_bit(unsigned int nr, const u8 *addr)
 {
@@ -1726,6 +1748,7 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
 		{ BIT_FAST_INTR_STAT_MERR, sii8620_irq_merr },
 		{ BIT_FAST_INTR_STAT_BLOCK, sii8620_irq_block },
 		{ BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid },
+		{ BIT_FAST_INTR_STAT_DDC, sii8620_irq_ddc },
 		{ BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt },
 		{ BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr },
 	};
-- 
2.7.4

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

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

* [PATCH 18/24] drm/bridge/sii8620: fix disconnect sequence
       [not found]   ` <CGME20170120073900eucas1p158ae6deea9833bac7f8a2f1199878f15@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

The patch allows to avoid rare cases when discovery fails.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index d0e6dc3..1c76905 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1286,10 +1286,12 @@ static void sii8620_disconnect(struct sii8620 *ctx)
 {
 	sii8620_disable_gen2_write_burst(ctx);
 	sii8620_stop_video(ctx);
-	msleep(50);
+	msleep(100);
 	sii8620_cbus_reset(ctx);
 	sii8620_set_mode(ctx, CM_DISCONNECTED);
 	sii8620_write_seq_static(ctx,
+		REG_TX_ZONE_CTL1, 0,
+		REG_MHL_PLL_CTL0, 0x07,
 		REG_COC_CTL0, 0x40,
 		REG_CBUS3_CNVT, 0x84,
 		REG_COC_CTL14, 0x00,
-- 
2.7.4

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

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

* [PATCH 19/24] drm/bridge/sii8620: rewrite hdmi start sequence
       [not found]   ` <CGME20170120073900eucas1p1b08b14e7cee9378d3b61016370a0ebef@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  2017-01-23  9:17       ` Archit Taneja
  0 siblings, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL3 protocol requires registry adjustments depending on chosen video mode.
Necessary information is gathered in mode_fixup callback. In case of HDMI
video modes driver should also send special AVI and MHL infoframes.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 249 +++++++++++++++++++++++++++++++----
 drivers/gpu/drm/bridge/sil-sii8620.h |  15 ++-
 2 files changed, 231 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 1c76905..2c7b5b9 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -32,6 +32,8 @@
 
 #define SII8620_BURST_BUF_LEN 288
 #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
+#define MHL1_MAX_LCLK 225000
+#define MHL3_MAX_LCLK 600000
 
 enum sii8620_mode {
 	CM_DISCONNECTED,
@@ -62,6 +64,9 @@ struct sii8620 {
 	struct regulator_bulk_data supplies[2];
 	struct mutex lock; /* context lock, protects fields below */
 	int error;
+	int pixel_clock;
+	unsigned int use_packed_pixel:1;
+	int video_code;
 	enum sii8620_mode mode;
 	enum sii8620_sink_type sink_type;
 	u8 cbus_status;
@@ -69,7 +74,7 @@ struct sii8620 {
 	u8 xstat[MHL_XDS_SIZE];
 	u8 devcap[MHL_DCAP_SIZE];
 	u8 xdevcap[MHL_XDC_SIZE];
-	u8 avif[19];
+	u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
 	struct edid *edid;
 	unsigned int gen2_write_burst:1;
 	enum sii8620_mt_state mt_state;
@@ -685,6 +690,40 @@ static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
 	d->size = cpu_to_le16(size);
 }
 
+static u8 sii8620_checksum(void *ptr, int size)
+{
+	u8 *d = ptr, sum = 0;
+
+	while (size--)
+		sum += *d++;
+
+	return sum;
+}
+
+static void sii8620_mhl_burst_hdr_set(struct mhl3_burst_header *h,
+	enum mhl_burst_id id)
+{
+	h->id = cpu_to_be16(id);
+	h->total_entries = 1;
+	h->sequence_index = 1;
+}
+
+static void sii8620_burst_tx_bits_per_pixel_fmt(struct sii8620 *ctx, u8 fmt)
+{
+	struct mhl_burst_bits_per_pixel_fmt *d;
+	const int size = sizeof(*d) + sizeof(d->desc[0]);
+
+	d = sii8620_burst_get_tx_buf(ctx, size);
+	if (!d)
+		return;
+
+	sii8620_mhl_burst_hdr_set(&d->hdr, MHL_BURST_ID_BITS_PER_PIXEL_FMT);
+	d->num_entries = 1;
+	d->desc[0].stream_id = 0;
+	d->desc[0].pixel_format = fmt;
+	d->hdr.checksum -= sii8620_checksum(d, size);
+}
+
 static void sii8620_burst_rx_all(struct sii8620 *ctx)
 {
 	u8 *d = ctx->burst.rx_buf;
@@ -949,32 +988,162 @@ static void sii8620_stop_video(struct sii8620 *ctx)
 	sii8620_write(ctx, REG_TPI_SC, val);
 }
 
+static void sii8620_set_format(struct sii8620 *ctx)
+{
+	u8 out_fmt;
+
+	if (sii8620_is_mhl3(ctx)) {
+		sii8620_setbits(ctx, REG_M3_P0CTRL,
+				BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
+				ctx->use_packed_pixel ? ~0 : 0);
+	} else {
+		if (ctx->use_packed_pixel)
+			sii8620_write_seq_static(ctx,
+				REG_VID_MODE, BIT_VID_MODE_M1080P,
+				REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1,
+				REG_MHLTX_CTL6, 0x60
+			);
+		else
+			sii8620_write_seq_static(ctx,
+				REG_VID_MODE, 0,
+				REG_MHL_TOP_CTL, 1,
+				REG_MHLTX_CTL6, 0xa0
+			);
+	}
+
+	if (ctx->use_packed_pixel)
+		out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL) |
+			BIT_TPI_OUTPUT_CSCMODE709;
+	else
+		out_fmt = VAL_TPI_FORMAT(RGB, FULL);
+
+	sii8620_write_seq(ctx,
+		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
+		REG_TPI_OUTPUT, out_fmt,
+	);
+}
+
+#define MHL3_VSIF_TYPE		0x81
+#define MHL3_VSIF_VERSION	0x03
+#define MHL3_VSIF_LENGTH	0x0f
+#define IEEE_OUI_MHL3		0x7CA61D
+
+static void sii8620_mhl_infoframe_init(void *ptr, int size)
+{
+	u8 *buf = ptr;
+
+	memset(buf, 0, size);
+	buf[0] = MHL3_VSIF_TYPE;
+	buf[1] = MHL3_VSIF_VERSION;
+	buf[2] = MHL3_VSIF_LENGTH;
+	buf[4] = IEEE_OUI_MHL3 & 0xff;
+	buf[5] = (IEEE_OUI_MHL3 >> 8) & 0xff;
+	buf[6] = (IEEE_OUI_MHL3 >> 16) & 0xff;
+	buf[3] -= sii8620_checksum(buf, MHL3_VSIF_LENGTH);
+}
+
+static void sii8620_set_infoframes(struct sii8620 *ctx)
+{
+	union hdmi_infoframe frm;
+	u8 buf[31];
+	int ret;
+
+	if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) {
+		sii8620_write(ctx, REG_TPI_SC,
+			BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
+		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif + 3,
+			ARRAY_SIZE(ctx->avif) - 3);
+		sii8620_write(ctx, REG_PKT_FILTER_0,
+			BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
+			BIT_PKT_FILTER_0_DROP_MPEG_PKT |
+			BIT_PKT_FILTER_0_DROP_GCP_PKT,
+			BIT_PKT_FILTER_1_DROP_GEN_PKT);
+		return;
+	}
+
+	ret = hdmi_avi_infoframe_init(&frm.avi);
+	frm.avi.colorspace = HDMI_COLORSPACE_YUV422;
+	frm.avi.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
+	frm.avi.picture_aspect = HDMI_PICTURE_ASPECT_16_9;
+	frm.avi.colorimetry = HDMI_COLORIMETRY_ITU_709;
+	frm.avi.video_code = ctx->video_code;
+	if (!ret)
+		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, ARRAY_SIZE(buf));
+	if (ret > 0)
+		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3);
+	sii8620_write(ctx, REG_PKT_FILTER_0,
+		BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
+		BIT_PKT_FILTER_0_DROP_MPEG_PKT |
+		BIT_PKT_FILTER_0_DROP_AVI_PKT |
+		BIT_PKT_FILTER_0_DROP_GCP_PKT,
+		BIT_PKT_FILTER_1_VSI_OVERRIDE_DIS |
+		BIT_PKT_FILTER_1_DROP_GEN_PKT |
+		BIT_PKT_FILTER_1_DROP_VSIF_PKT);
+
+	sii8620_write(ctx, REG_TPI_INFO_FSEL, BIT_TPI_INFO_FSEL_EN
+		| BIT_TPI_INFO_FSEL_RPT | VAL_TPI_INFO_FSEL_VSI);
+	sii8620_mhl_infoframe_init(buf, ARRAY_SIZE(buf));
+	sii8620_write_buf(ctx, REG_TPI_INFO_B0, buf, ARRAY_SIZE(buf));
+}
+
 static void sii8620_start_hdmi(struct sii8620 *ctx)
 {
 	sii8620_write_seq_static(ctx,
 		REG_RX_HDMI_CTRL2, VAL_RX_HDMI_CTRL2_DEFVAL
 			| BIT_RX_HDMI_CTRL2_USE_AV_MUTE,
 		REG_VID_OVRRD, BIT_VID_OVRRD_PP_AUTO_DISABLE
-			| BIT_VID_OVRRD_M1080P_OVRRD,
-		REG_VID_MODE, 0,
-		REG_MHL_TOP_CTL, 0x1,
-		REG_MHLTX_CTL6, 0xa0,
-		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
-		REG_TPI_OUTPUT, VAL_TPI_FORMAT(RGB, FULL),
-	);
+			| BIT_VID_OVRRD_M1080P_OVRRD);
+	sii8620_set_format(ctx);
 
-	sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
-			      MHL_DST_LM_CLK_MODE_NORMAL |
-			      MHL_DST_LM_PATH_ENABLED);
-
-	sii8620_set_auto_zone(ctx);
+	if (!sii8620_is_mhl3(ctx)) {
+		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
+			MHL_DST_LM_CLK_MODE_NORMAL | MHL_DST_LM_PATH_ENABLED);
+		sii8620_set_auto_zone(ctx);
+	} else {
+		static const struct {
+			int max_clk;
+			u8 zone;
+			u8 link_rate;
+			u8 rrp_decode;
+		} clk_spec[] = {
+			{ 150000, VAL_TX_ZONE_CTL3_TX_ZONE_1_5GBPS,
+			  MHL_XDS_LINK_RATE_1_5_GBPS, 0x38 },
+			{ 300000, VAL_TX_ZONE_CTL3_TX_ZONE_3GBPS,
+			  MHL_XDS_LINK_RATE_3_0_GBPS, 0x40 },
+			{ 600000, VAL_TX_ZONE_CTL3_TX_ZONE_6GBPS,
+			  MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 },
+		};
+		u8 p0_ctrl = BIT_M3_P0CTRL_MHL3_P0_PORT_EN;
+		int clk = ctx->pixel_clock * (ctx->use_packed_pixel ? 2 : 3);
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(clk_spec); ++i)
+			if (clk < clk_spec[i].max_clk)
+				break;
 
-	sii8620_write(ctx, REG_TPI_SC, BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
+		if (100 * clk >= 98 * clk_spec[i].max_clk)
+			p0_ctrl |= BIT_M3_P0CTRL_MHL3_P0_UNLIMIT_EN;
 
-	sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif,
-			  ARRAY_SIZE(ctx->avif));
+		sii8620_burst_tx_bits_per_pixel_fmt(ctx, ctx->use_packed_pixel);
+		sii8620_burst_send(ctx);
+		sii8620_write_seq(ctx,
+			REG_MHL_DP_CTL0, 0xf0,
+			REG_MHL3_TX_ZONE_CTL, clk_spec[i].zone);
+		sii8620_setbits(ctx, REG_M3_P0CTRL,
+			BIT_M3_P0CTRL_MHL3_P0_PORT_EN
+			| BIT_M3_P0CTRL_MHL3_P0_UNLIMIT_EN, p0_ctrl);
+		sii8620_setbits(ctx, REG_M3_POSTM, MSK_M3_POSTM_RRP_DECODE,
+			clk_spec[i].rrp_decode);
+		sii8620_write_seq_static(ctx,
+			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE
+				| BIT_M3_CTRL_H2M_SWRST,
+			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE
+		);
+		sii8620_mt_write_stat(ctx, MHL_XDS_REG(AVLINK_MODE_CONTROL),
+			clk_spec[i].link_rate);
+	}
 
-	sii8620_write(ctx, REG_PKT_FILTER_0, 0xa1, 0x2);
+	sii8620_set_infoframes(ctx);
 }
 
 static void sii8620_start_video(struct sii8620 *ctx)
@@ -1834,22 +2003,44 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge,
 			       struct drm_display_mode *adjusted_mode)
 {
 	struct sii8620 *ctx = bridge_to_sii8620(bridge);
-	bool ret = false;
-	int max_clock = 74250;
-
-	mutex_lock(&ctx->lock);
-
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		goto out;
+	int max_lclk;
+	bool ret = true;
 
-	if (ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL)
-		max_clock = 300000;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return false;
 
-	ret = mode->clock <= max_clock;
+	mutex_lock(&ctx->lock);
 
-out:
+	max_lclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : MHL1_MAX_LCLK;
+	if (max_lclk > 3 * adjusted_mode->clock) {
+		ctx->use_packed_pixel = 0;
+		goto end;
+	}
+	if ((ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL) &&
+	    max_lclk > 2 * adjusted_mode->clock) {
+		ctx->use_packed_pixel = 1;
+		goto end;
+	}
+	ret = false;
+end:
+	if (ret) {
+		u8 vic = drm_match_cea_mode(adjusted_mode);
+
+		if (!vic) {
+			union hdmi_infoframe frm;
+			u8 mhl_vic[] = { 0, 95, 94, 93, 98 };
+
+			drm_hdmi_vendor_infoframe_from_display_mode(
+				&frm.vendor.hdmi, adjusted_mode);
+			vic = frm.vendor.hdmi.vic;
+			if (vic >= ARRAY_SIZE(mhl_vic))
+				vic = 0;
+			vic = mhl_vic[vic];
+		}
+		ctx->video_code = vic;
+		ctx->pixel_clock = adjusted_mode->clock;
+	}
 	mutex_unlock(&ctx->lock);
-
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index f7bfbc3..aefae67 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -1084,10 +1084,17 @@
 
 /* TPI Info Frame Select, default value: 0x00 */
 #define REG_TPI_INFO_FSEL			0x06bf
-#define BIT_TPI_INFO_FSEL_TPI_INFO_EN		BIT(7)
-#define BIT_TPI_INFO_FSEL_TPI_INFO_RPT		BIT(6)
-#define BIT_TPI_INFO_FSEL_TPI_INFO_READ_FLAG	BIT(5)
-#define MSK_TPI_INFO_FSEL_TPI_INFO_SEL		0x07
+#define BIT_TPI_INFO_FSEL_EN			BIT(7)
+#define BIT_TPI_INFO_FSEL_RPT			BIT(6)
+#define BIT_TPI_INFO_FSEL_READ_FLAG		BIT(5)
+#define MSK_TPI_INFO_FSEL_PKT			0x07
+#define VAL_TPI_INFO_FSEL_AVI			0x00
+#define VAL_TPI_INFO_FSEL_SPD			0x01
+#define VAL_TPI_INFO_FSEL_AUD			0x02
+#define VAL_TPI_INFO_FSEL_MPG			0x03
+#define VAL_TPI_INFO_FSEL_GEN			0x04
+#define VAL_TPI_INFO_FSEL_GEN2			0x05
+#define VAL_TPI_INFO_FSEL_VSI			0x06
 
 /* TPI Info Byte #0, default value: 0x00 */
 #define REG_TPI_INFO_B0				0x06c0
-- 
2.7.4

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

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

* [PATCH 20/24] drm/bridge/sii8620: send EMSC features on request
       [not found]   ` <CGME20170120073901eucas1p134403a09cc3ac008c9a3285b31aef888@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Device should report to the peer which features are really supported.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 27 +++++++++++++++++++++++----
 drivers/gpu/drm/bridge/sil-sii8620.h | 16 ++++++++--------
 2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 2c7b5b9..2cc197d 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1644,6 +1644,25 @@ static void sii8620_got_ecbus_speed(struct sii8620 *ctx, int ret)
 	sii8620_mt_set_cont(ctx, sii8620_ecbus_up);
 }
 
+static void sii8620_mhl_burst_emsc_support_set(struct mhl_burst_emsc_support *d,
+	enum mhl_burst_id id)
+{
+	sii8620_mhl_burst_hdr_set(&d->hdr, MHL_BURST_ID_EMSC_SUPPORT);
+	d->num_entries = 1;
+	d->burst_id[0] = cpu_to_be16(id);
+}
+
+static void sii8620_send_features(struct sii8620 *ctx)
+{
+	u8 buf[16];
+
+	sii8620_write(ctx, REG_MDT_XMIT_CTRL, BIT_MDT_XMIT_CTRL_EN
+		| BIT_MDT_XMIT_CTRL_FIXED_BURST_LEN);
+	sii8620_mhl_burst_emsc_support_set((void *)buf,
+		MHL_BURST_ID_HID_PAYLOAD);
+	sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf));
+}
+
 static void sii8620_msc_mr_set_int(struct sii8620 *ctx)
 {
 	u8 ints[MHL_INT_SIZE];
@@ -1664,10 +1683,10 @@ static void sii8620_msc_mr_set_int(struct sii8620 *ctx)
 			break;
 		}
 	}
-	if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_REQ) {
-		sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE),
-				   MHL_INT_RC_FEAT_COMPLETE);
-	}
+	if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_REQ)
+		sii8620_send_features(ctx);
+	if (ints[MHL_INT_RCHANGE] & MHL_INT_RC_FEAT_COMPLETE)
+		sii8620_edid_read(ctx, 0);
 }
 
 static struct sii8620_mt_msg *sii8620_msc_msg_first(struct sii8620 *ctx)
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index aefae67..e42c1c3 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -1298,14 +1298,14 @@
 
 /* MDT Transmit Control, default value: 0x70 */
 #define REG_MDT_XMIT_CTRL			0x0588
-#define BIT_MDT_XMIT_CTRL_MDT_XMIT_EN		BIT(7)
-#define BIT_MDT_XMIT_CTRL_MDT_XMIT_CMD_MERGE_EN	BIT(6)
-#define BIT_MDT_XMIT_CTRL_MDT_XMIT_FIXED_BURST_LEN BIT(5)
-#define BIT_MDT_XMIT_CTRL_MDT_XMIT_FIXED_AID	BIT(4)
-#define BIT_MDT_XMIT_CTRL_MDT_XMIT_SINGLE_RUN_EN BIT(3)
-#define BIT_MDT_XMIT_CTRL_MDT_CLR_ABORT_WAIT	BIT(2)
-#define BIT_MDT_XMIT_CTRL_MDT_XFIFO_CLR_ALL	BIT(1)
-#define BIT_MDT_XMIT_CTRL_MDT_XFIFO_CLR_CUR	BIT(0)
+#define BIT_MDT_XMIT_CTRL_EN			BIT(7)
+#define BIT_MDT_XMIT_CTRL_CMD_MERGE_EN		BIT(6)
+#define BIT_MDT_XMIT_CTRL_FIXED_BURST_LEN 	BIT(5)
+#define BIT_MDT_XMIT_CTRL_FIXED_AID		BIT(4)
+#define BIT_MDT_XMIT_CTRL_SINGLE_RUN_EN		BIT(3)
+#define BIT_MDT_XMIT_CTRL_CLR_ABORT_WAIT	BIT(2)
+#define BIT_MDT_XMIT_CTRL_XFIFO_CLR_ALL		BIT(1)
+#define BIT_MDT_XMIT_CTRL_XFIFO_CLR_CUR		BIT(0)
 
 /* MDT Receive WRITE Port, default value: 0x00 */
 #define REG_MDT_XMIT_WRITE_PORT			0x0589
-- 
2.7.4

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

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

* [PATCH 21/24] drm/bridge/sii8620: improve gen2 write burst IRQ routine
       [not found]   ` <CGME20170120073901eucas1p1c4c9ca4b72fc1e418775f59e6c3579f2@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

The patch adds code to report back feature complete IRQ, and code
to read and drop burst writes from peer.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 2cc197d..77c9fb2 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1573,12 +1573,31 @@ static void sii8620_irq_disc(struct sii8620 *ctx)
 	sii8620_write(ctx, REG_CBUS_DISC_INTR0, stat);
 }
 
+static void sii8620_read_burst(struct sii8620 *ctx)
+{
+	u8 buf[17];
+
+	sii8620_read_buf(ctx, REG_MDT_RCV_READ_PORT, buf, ARRAY_SIZE(buf));
+	sii8620_write(ctx, REG_MDT_RCV_CTRL, BIT_MDT_RCV_CTRL_MDT_RCV_EN |
+		      BIT_MDT_RCV_CTRL_MDT_DELAY_RCV_EN |
+		      BIT_MDT_RCV_CTRL_MDT_RFIFO_CLR_CUR);
+	sii8620_readb(ctx, REG_MDT_RFIFO_STAT);
+}
+
 static void sii8620_irq_g2wb(struct sii8620 *ctx)
 {
 	u8 stat = sii8620_readb(ctx, REG_MDT_INT_0);
 
 	if (stat & BIT_MDT_IDLE_AFTER_HAWB_DISABLE)
-		dev_dbg(ctx->dev, "HAWB idle\n");
+		if (sii8620_is_mhl3(ctx))
+			sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE),
+				MHL_INT_RC_FEAT_COMPLETE);
+
+	if (stat & BIT_MDT_RFIFO_DATA_RDY)
+		sii8620_read_burst(ctx);
+
+	if (stat & BIT_MDT_XFIFO_EMPTY)
+		sii8620_write(ctx, REG_MDT_XMIT_CTRL, 0);
 
 	sii8620_write(ctx, REG_MDT_INT_0, stat);
 }
-- 
2.7.4

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

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

* [PATCH 22/24] drm/bridge/sii8620: add HSIC initialization code
       [not found]   ` <CGME20170120073901eucas1p1f254c73eb4c49024b575f4ab02d56b65@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

In case of MHL3 HSIC should be initialized.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 38 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/sil-sii8620.h | 10 ++++++----
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 77c9fb2..50bfb3c 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -489,12 +489,50 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret)
 		 sink_str[ctx->sink_type], sink_name);
 }
 
+static void sii8620_hsic_init(struct sii8620 *ctx)
+{
+	if (!sii8620_is_mhl3(ctx))
+		return;
+
+	sii8620_write(ctx, REG_FCGC,
+		BIT_FCGC_HSIC_HOSTMODE | BIT_FCGC_HSIC_ENABLE);
+	sii8620_setbits(ctx, REG_HRXCTRL3,
+		BIT_HRXCTRL3_HRX_STAY_RESET | BIT_HRXCTRL3_STATUS_EN, ~0);
+	sii8620_setbits(ctx, REG_TTXNUMB, MSK_TTXNUMB_TTX_NUMBPS, 4);
+	sii8620_setbits(ctx, REG_TRXCTRL, BIT_TRXCTRL_TRX_FROM_SE_COC, ~0);
+	sii8620_setbits(ctx, REG_HTXCTRL, BIT_HTXCTRL_HTX_DRVCONN1, 0);
+	sii8620_setbits(ctx, REG_KEEPER, MSK_KEEPER_MODE, VAL_KEEPER_MODE_HOST);
+	sii8620_write_seq_static(ctx,
+		REG_TDMLLCTL, 0,
+		REG_UTSRST, BIT_UTSRST_HRX_SRST | BIT_UTSRST_HTX_SRST |
+			BIT_UTSRST_KEEPER_SRST | BIT_UTSRST_FC_SRST,
+		REG_UTSRST, BIT_UTSRST_HRX_SRST | BIT_UTSRST_HTX_SRST,
+		REG_HRXINTL, 0xff,
+		REG_HRXINTH, 0xff,
+		REG_TTXINTL, 0xff,
+		REG_TTXINTH, 0xff,
+		REG_TRXINTL, 0xff,
+		REG_TRXINTH, 0xff,
+		REG_HTXINTL, 0xff,
+		REG_HTXINTH, 0xff,
+		REG_FCINTR0, 0xff,
+		REG_FCINTR1, 0xff,
+		REG_FCINTR2, 0xff,
+		REG_FCINTR3, 0xff,
+		REG_FCINTR4, 0xff,
+		REG_FCINTR5, 0xff,
+		REG_FCINTR6, 0xff,
+		REG_FCINTR7, 0xff
+	);
+}
+
 static void sii8620_edid_read(struct sii8620 *ctx, int ret)
 {
 	if (ret < 0)
 		return;
 
 	sii8620_set_upstream_edid(ctx);
+	sii8620_hsic_init(ctx);
 	sii8620_enable_hpd(ctx);
 }
 
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index e42c1c3..30cc992 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -353,7 +353,7 @@
 #define REG_TTXNUMB				0x0116
 #define MSK_TTXNUMB_TTX_AFFCTRL_3_0		0xf0
 #define BIT_TTXNUMB_TTX_COM1_AT_SYNC_WAIT	BIT(3)
-#define MSK_TTXNUMB_TTX_NUMBPS_2_0		0x07
+#define MSK_TTXNUMB_TTX_NUMBPS			0x07
 
 /* TDM TX NUMSPISYM, default value: 0x04 */
 #define REG_TTXSPINUMS				0x0117
@@ -433,12 +433,14 @@
 
 /* HSIC Keeper, default value: 0x00 */
 #define REG_KEEPER				0x0181
-#define MSK_KEEPER_KEEPER_MODE_1_0		0x03
+#define MSK_KEEPER_MODE				0x03
+#define VAL_KEEPER_MODE_HOST			0
+#define VAL_KEEPER_MODE_DEVICE			2
 
 /* HSIC Flow Control General, default value: 0x02 */
 #define REG_FCGC				0x0183
-#define BIT_FCGC_HSIC_FC_HOSTMODE		BIT(1)
-#define BIT_FCGC_HSIC_FC_ENABLE			BIT(0)
+#define BIT_FCGC_HSIC_HOSTMODE			BIT(1)
+#define BIT_FCGC_HSIC_ENABLE			BIT(0)
 
 /* HSIC Flow Control CTR13, default value: 0xfc */
 #define REG_FCCTR13				0x0191
-- 
2.7.4

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

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

* [PATCH 23/24] drm/bridge/sii8620: enable MHL3 mode if possible
       [not found]   ` <CGME20170120073902eucas1p27c5b9a57fa5461e227ad090b17af0e8c@eucas1p2.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Since all sub-protocols of MHL3 are already supported MHL3 mode can be enabled.
With this patch it is possible to use packed pixel modes and clocks up
to 300MHz - 1920x1080@60Hz and 4K modes.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 50bfb3c..57ad0b4 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1372,8 +1372,7 @@ static void sii8620_mhl_init(struct sii8620 *ctx)
 	);
 	sii8620_disable_gen2_write_burst(ctx);
 
-	/* currently MHL3 is not supported, so we force version to 0 */
-	sii8620_mt_write_stat(ctx, MHL_DST_REG(VERSION), 0);
+	sii8620_mt_write_stat(ctx, MHL_DST_REG(VERSION), SII8620_MHL_VERSION);
 	sii8620_mt_write_stat(ctx, MHL_DST_REG(CONNECTED_RDY),
 			      MHL_DST_CONN_DCAP_RDY | MHL_DST_CONN_XDEVCAPP_SUPP
 			      | MHL_DST_CONN_POW_STAT);
@@ -1640,14 +1639,16 @@ static void sii8620_irq_g2wb(struct sii8620 *ctx)
 	sii8620_write(ctx, REG_MDT_INT_0, stat);
 }
 
-static void sii8620_status_changed_dcap(struct sii8620 *ctx)
+static void sii8620_status_dcap_ready(struct sii8620 *ctx)
 {
-	if (ctx->stat[MHL_DST_CONNECTED_RDY] & MHL_DST_CONN_DCAP_RDY) {
-		sii8620_set_mode(ctx, CM_MHL1);
-		sii8620_peer_specific_init(ctx);
-		sii8620_write(ctx, REG_INTR9_MASK, BIT_INTR9_DEVCAP_DONE
-			       | BIT_INTR9_EDID_DONE | BIT_INTR9_EDID_ERROR);
-	}
+	enum sii8620_mode mode;
+
+	mode = ctx->stat[MHL_DST_VERSION] >= 0x30 ? CM_MHL3 : CM_MHL1;
+	if (mode > ctx->mode)
+		sii8620_set_mode(ctx, mode);
+	sii8620_peer_specific_init(ctx);
+	sii8620_write(ctx, REG_INTR9_MASK, BIT_INTR9_DEVCAP_DONE
+		      | BIT_INTR9_EDID_DONE | BIT_INTR9_EDID_ERROR);
 }
 
 static void sii8620_status_changed_path(struct sii8620 *ctx)
@@ -1675,8 +1676,8 @@ static void sii8620_msc_mr_write_stat(struct sii8620 *ctx)
 	sii8620_update_array(ctx->stat, st, MHL_DST_SIZE);
 	sii8620_update_array(ctx->xstat, xst, MHL_XDS_SIZE);
 
-	if (st[MHL_DST_CONNECTED_RDY] & MHL_DST_CONN_DCAP_RDY)
-		sii8620_status_changed_dcap(ctx);
+	if (ctx->stat[MHL_DST_CONNECTED_RDY] & MHL_DST_CONN_DCAP_RDY)
+		sii8620_status_dcap_ready(ctx);
 
 	if (st[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED)
 		sii8620_status_changed_path(ctx);
-- 
2.7.4

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

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

* [PATCH 24/24] drm/bridge/sii8620: enable interlace modes
       [not found]   ` <CGME20170120073902eucas1p145a70cf76319defe839cf5be0bba3870@eucas1p1.samsung.com>
@ 2017-01-20  7:38     ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-20  7:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Bug in DECON(CRTC) driver prevented interlace modes from proper work.
Since DECON is fixed interlace modes can be enabled in MHL.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 57ad0b4..d3c7c21 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -2083,9 +2083,6 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge,
 	int max_lclk;
 	bool ret = true;
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-		return false;
-
 	mutex_lock(&ctx->lock);
 
 	max_lclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : MHL1_MAX_LCLK;
-- 
2.7.4

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

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

* Re: [PATCH 07/24] drm/bridge/sii8620: add support for burst eMSC transmissions
  2017-01-20  7:38     ` [PATCH 07/24] drm/bridge/sii8620: add support for burst eMSC transmissions Andrzej Hajda
@ 2017-01-23  8:20       ` Archit Taneja
  2017-01-23 10:38         ` Andrzej Hajda
       [not found]         ` <CGME20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc@eucas1p2.samsung.com>
  0 siblings, 2 replies; 42+ messages in thread
From: Archit Taneja @ 2017-01-23  8:20 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
> Burst transmissions are used in MHL3 mode negotiation.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/bridge/sil-sii8620.c | 196 ++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/bridge/sil-sii8620.h |   4 +
>  2 files changed, 198 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 9f9fd99..744e685 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -9,6 +9,8 @@
>   * published by the Free Software Foundation.
>   */
>
> +#include <asm/unaligned.h>
> +
>  #include <drm/bridge/mhl.h>
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_edid.h>
> @@ -28,7 +30,8 @@
>
>  #include "sil-sii8620.h"
>
> -#define VAL_RX_HDMI_CTRL2_DEFVAL	VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
> +#define SII8620_BURST_BUF_LEN 288
> +#define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
>
>  enum sii8620_mode {
>  	CM_DISCONNECTED,
> @@ -71,6 +74,15 @@ struct sii8620 {
>  	unsigned int gen2_write_burst:1;
>  	enum sii8620_mt_state mt_state;
>  	struct list_head mt_queue;
> +	struct {
> +		int r_size;
> +		int r_count;
> +		int rx_ack;
> +		int rx_count;
> +		u8 rx_buf[32];
> +		int tx_count;
> +		u8 tx_buf[32];
> +	} burst;
>  };
>
>  struct sii8620_mt_msg;
> @@ -511,6 +523,134 @@ static inline void sii8620_mt_read_xdevcap_reg(struct sii8620 *ctx, u8 reg)
>  	sii8620_mt_read_devcap_reg(ctx, reg | 0x80);
>  }
>
> +static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)
> +{
> +	u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];
> +	int size = len + 2;
> +
> +	if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
> +		dev_err(ctx->dev, "TX-BLK buffer exhausted\n");
> +		ctx->error = -EINVAL;
> +		return NULL;
> +	}
> +
> +	ctx->burst.tx_count += size;
> +	buf[1] = len;
> +
> +	return buf + 2;
> +}
> +
> +static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)
> +{
> +	u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];
> +	int size = len + 1;
> +
> +	if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
> +		dev_err(ctx->dev, "RX-BLK buffer exhausted\n");
> +		ctx->error = -EINVAL;
> +		return NULL;
> +	}
> +
> +	ctx->burst.rx_count += size;
> +	buf[0] = len;
> +
> +	return buf + 1;
> +}
> +
> +static void sii8620_burst_send(struct sii8620 *ctx)
> +{
> +	int tx_left = ctx->burst.tx_count;
> +	u8 *d = ctx->burst.tx_buf;
> +
> +	while (tx_left > 0) {
> +		int len = d[1] + 2;
> +
> +		if (ctx->burst.r_count + len > ctx->burst.r_size)
> +			break;
> +		d[0] = min(ctx->burst.rx_ack, 255);
> +		ctx->burst.rx_ack -= d[0];
> +		sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, d, len);
> +		ctx->burst.r_count += len;
> +		tx_left -= len;
> +		d += len;
> +	}
> +
> +	ctx->burst.tx_count = tx_left;
> +
> +	while (ctx->burst.rx_ack > 0) {
> +		u8 b[2] = { min(ctx->burst.rx_ack, 255), 0 };
> +
> +		if (ctx->burst.r_count + 2 > ctx->burst.r_size)
> +			break;
> +		ctx->burst.rx_ack -= b[0];
> +		sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, b, 2);
> +		ctx->burst.r_count += 2;
> +	}
> +}
> +
> +static void sii8620_burst_receive(struct sii8620 *ctx)
> +{
> +	u8 buf[3], *d;
> +	int count;
> +
> +	sii8620_read_buf(ctx, REG_EMSCRFIFOBCNTL, buf, 2);
> +	count = get_unaligned_le16(buf);
> +	while (count > 0) {
> +		int len = min(count, 3);
> +
> +		sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, buf, len);
> +		count -= len;
> +		ctx->burst.rx_ack += len - 1;
> +		ctx->burst.r_count -= buf[1];
> +		if (ctx->burst.r_count < 0)
> +			ctx->burst.r_count = 0;
> +
> +		if (len < 3 || !buf[2])
> +			continue;
> +
> +		len = buf[2];
> +		d = sii8620_burst_get_rx_buf(ctx, len);
> +		if (!d)
> +			continue;
> +		sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, d, len);
> +		count -= len;
> +		ctx->burst.rx_ack += len;
> +	}
> +}
> +
> +static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
> +{
> +	struct mhl_burst_blk_rcv_buffer_info *d =
> +		sii8620_burst_get_tx_buf(ctx, sizeof(*d));
> +	if (!d)
> +		return;
> +
> +	d->id = cpu_to_be16(MHL_BURST_ID_BLK_RCV_BUFFER_INFO);
> +	d->size = cpu_to_le16(size);
> +}
> +
> +static void sii8620_burst_rx_all(struct sii8620 *ctx)
> +{
> +	u8 *d = ctx->burst.rx_buf;
> +	int count = ctx->burst.rx_count;
> +
> +	while (count-- > 0) {
> +		int len = *d++;
> +		int id = get_unaligned_be16(&d[0]);
> +
> +		switch (id) {
> +		case MHL_BURST_ID_BLK_RCV_BUFFER_INFO:
> +			ctx->burst.r_size = get_unaligned_le16(&d[2]);
> +			break;
> +		default:
> +			break;
> +		}
> +		count -= len;
> +		d += len;
> +	}
> +	ctx->burst.rx_count = 0;
> +}
> +
>  static void sii8620_fetch_edid(struct sii8620 *ctx)
>  {
>  	u8 lm_ddc, ddc_cmd, int3, cbus;
> @@ -1041,7 +1181,7 @@ static int sii8620_wait_for_fsm_state(struct sii8620 *ctx, u8 state)
>
>  		if ((s & MSK_COC_STAT_0_FSM_STATE) == state)
>  			return 0;
> -		if (s & BIT_COC_STAT_0_PLL_LOCKED)
> +		if (!(s & BIT_COC_STAT_0_PLL_LOCKED))

Should this be a part of patch #5?

>  			return -EBUSY;
>  		usleep_range(4000, 6000);
>  	}
> @@ -1417,6 +1557,19 @@ static void sii8620_irq_coc(struct sii8620 *ctx)
>  {
>  	u8 stat = sii8620_readb(ctx, REG_COC_INTR);
>
> +	if (stat & BIT_COC_CALIBRATION_DONE) {
> +		u8 cstat = sii8620_readb(ctx, REG_COC_STAT_0);
> +
> +		cstat &= BIT_COC_STAT_0_PLL_LOCKED | MSK_COC_STAT_0_FSM_STATE;
> +		if (cstat == (BIT_COC_STAT_0_PLL_LOCKED | 0x02)) {
> +			sii8620_write_seq_static(ctx,
> +				REG_COC_CTLB, 0,
> +				REG_TRXINTMH, BIT_TDM_INTR_SYNC_DATA
> +					      | BIT_TDM_INTR_SYNC_WAIT
> +			);
> +		}
> +	}
> +
>  	sii8620_write(ctx, REG_COC_INTR, stat);
>  }
>
> @@ -1507,6 +1660,41 @@ static void sii8620_irq_infr(struct sii8620 *ctx)
>  		sii8620_start_video(ctx);
>  }
>
> +static void sii8620_irq_tdm(struct sii8620 *ctx)
> +{
> +	u8 stat = sii8620_readb(ctx, REG_TRXINTH);
> +	u8 tdm = sii8620_readb(ctx, REG_TRXSTA2);
> +
> +	if ((tdm & MSK_TDM_SYNCHRONIZED) == VAL_TDM_SYNCHRONIZED) {
> +		ctx->mode = CM_ECBUS_S;
> +		ctx->burst.rx_ack = 0;
> +		ctx->burst.r_size = SII8620_BURST_BUF_LEN;
> +		sii8620_burst_tx_rbuf_info(ctx, SII8620_BURST_BUF_LEN);
> +		sii8620_mt_read_devcap(ctx, true);
> +	} else {
> +		sii8620_write_seq_static(ctx,
> +			REG_MHL_PLL_CTL2, 0,
> +			REG_MHL_PLL_CTL2, BIT_MHL_PLL_CTL2_CLKDETECT_EN
> +		);
> +	}
> +
> +	sii8620_write(ctx, REG_TRXINTH, stat);
> +}
> +
> +static void sii8620_irq_block(struct sii8620 *ctx)
> +{
> +	u8 stat = sii8620_readb(ctx, REG_EMSCINTR);
> +
> +	if (stat & BIT_EMSCINTR_SPI_DVLD) {
> +		u8 bstat = sii8620_readb(ctx, REG_SPIBURSTSTAT);
> +
> +		if (bstat & BIT_SPIBURSTSTAT_EMSC_NORMAL_MODE)
> +			sii8620_burst_receive(ctx);
> +	}
> +
> +	sii8620_write(ctx, REG_EMSCINTR, stat);
> +}
> +
>  /* endian agnostic, non-volatile version of test_bit */
>  static bool sii8620_test_bit(unsigned int nr, const u8 *addr)
>  {
> @@ -1522,8 +1710,10 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
>  		{ BIT_FAST_INTR_STAT_DISC, sii8620_irq_disc },
>  		{ BIT_FAST_INTR_STAT_G2WB, sii8620_irq_g2wb },
>  		{ BIT_FAST_INTR_STAT_COC, sii8620_irq_coc },
> +		{ BIT_FAST_INTR_STAT_TDM, sii8620_irq_tdm },
>  		{ BIT_FAST_INTR_STAT_MSC, sii8620_irq_msc },
>  		{ BIT_FAST_INTR_STAT_MERR, sii8620_irq_merr },
> +		{ BIT_FAST_INTR_STAT_BLOCK, sii8620_irq_block },
>  		{ BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid },
>  		{ BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt },
>  		{ BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr },
> @@ -1539,7 +1729,9 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
>  		if (sii8620_test_bit(irq_vec[i].bit, stats))
>  			irq_vec[i].handler(ctx);
>
> +	sii8620_burst_rx_all(ctx);
>  	sii8620_mt_work(ctx);
> +	sii8620_burst_send(ctx);
>
>  	ret = sii8620_clear_error(ctx);
>  	if (ret) {
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
> index 3ee4e7e..f7bfbc3 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.h
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.h
> @@ -403,12 +403,16 @@
>
>  /* TDM RX Status 2nd, default value: 0x00 */
>  #define REG_TRXSTA2				0x015c
> +#define MSK_TDM_SYNCHRONIZED			0xC0

Would be nice to not have the hex digits in caps here.

Thanks,
Archit

> +#define VAL_TDM_SYNCHRONIZED			0x80
>
>  /* TDM RX INT Low, default value: 0x00 */
>  #define REG_TRXINTL				0x0163
>
>  /* TDM RX INT High, default value: 0x00 */
>  #define REG_TRXINTH				0x0164
> +#define BIT_TDM_INTR_SYNC_DATA			BIT(0)
> +#define BIT_TDM_INTR_SYNC_WAIT			BIT(1)
>
>  /* TDM RX INTMASK High, default value: 0x00 */
>  #define REG_TRXINTMH				0x0166
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 04/24] drm/bridge/sii8620: add continuations to messages
  2017-01-20  7:38     ` [PATCH 04/24] drm/bridge/sii8620: add continuations to messages Andrzej Hajda
@ 2017-01-23  8:31       ` Archit Taneja
  2017-01-23 10:33         ` Andrzej Hajda
       [not found]         ` <CGME20170126134315eucas1p1db71a5e2f14fd93283d14a2da4f05611@eucas1p1.samsung.com>
  0 siblings, 2 replies; 42+ messages in thread
From: Archit Taneja @ 2017-01-23  8:31 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
> Due to asynchronous nature of MHL flow of execution is dispersed. Logical
> continuation of some actions happens after response of peer, i.e in interrupt
> handler. To simplify coding continuation mechanism has been added - it is now
> possible to provide continuation callback, which will be called after peer
> responds to given action.

Could you wrap this to 75 chars?

>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/bridge/sil-sii8620.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 75867c0..cde0074 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -78,12 +78,15 @@ struct sii8620_mt_msg;
>  typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
>  				  struct sii8620_mt_msg *msg);
>
> +typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
> +
>  struct sii8620_mt_msg {
>  	struct list_head node;
>  	u8 reg[4];
>  	u8 ret;
>  	sii8620_mt_msg_cb send;
>  	sii8620_mt_msg_cb recv;
> +	sii8620_cb continuation;
>  };
>
>  static const u8 sii8620_i2c_page[] = {
> @@ -258,6 +261,8 @@ static void sii8620_mt_work(struct sii8620 *ctx)
>  				       node);
>  		if (msg->recv)
>  			msg->recv(ctx, msg);
> +		if (msg->continuation)
> +			msg->continuation(ctx, msg->ret);

I was wondering if instead of executing the continuation via a callback,
would it make sense to insert them as a new message instead?

I don't have the complete context of this, so feel free to ignore the suggestion
if doesn't make sense.

Thanks,
Archit

>  		list_del(&msg->node);
>  		kfree(msg);
>  	}
> @@ -310,6 +315,21 @@ static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx)
>  	return msg;
>  }
>
> +static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont)
> +{
> +	struct sii8620_mt_msg *msg;
> +
> +	if (ctx->error)
> +		return;
> +
> +	if (list_empty(&ctx->mt_queue)) {
> +		ctx->error = -EINVAL;
> +		return;
> +	}
> +	msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node);
> +	msg->continuation = cont;
> +}
> +
>  static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2)
>  {
>  	struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 19/24] drm/bridge/sii8620: rewrite hdmi start sequence
  2017-01-20  7:38     ` [PATCH 19/24] drm/bridge/sii8620: rewrite hdmi start sequence Andrzej Hajda
@ 2017-01-23  9:17       ` Archit Taneja
  2017-01-23 11:12         ` Andrzej Hajda
  0 siblings, 1 reply; 42+ messages in thread
From: Archit Taneja @ 2017-01-23  9:17 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
> MHL3 protocol requires registry adjustments depending on chosen video mode.
> Necessary information is gathered in mode_fixup callback. In case of HDMI
> video modes driver should also send special AVI and MHL infoframes.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/bridge/sil-sii8620.c | 249 +++++++++++++++++++++++++++++++----
>  drivers/gpu/drm/bridge/sil-sii8620.h |  15 ++-
>  2 files changed, 231 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 1c76905..2c7b5b9 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -32,6 +32,8 @@
>
>  #define SII8620_BURST_BUF_LEN 288
>  #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
> +#define MHL1_MAX_LCLK 225000
> +#define MHL3_MAX_LCLK 600000
>
>  enum sii8620_mode {
>  	CM_DISCONNECTED,
> @@ -62,6 +64,9 @@ struct sii8620 {
>  	struct regulator_bulk_data supplies[2];
>  	struct mutex lock; /* context lock, protects fields below */
>  	int error;
> +	int pixel_clock;
> +	unsigned int use_packed_pixel:1;
> +	int video_code;
>  	enum sii8620_mode mode;
>  	enum sii8620_sink_type sink_type;
>  	u8 cbus_status;
> @@ -69,7 +74,7 @@ struct sii8620 {
>  	u8 xstat[MHL_XDS_SIZE];
>  	u8 devcap[MHL_DCAP_SIZE];
>  	u8 xdevcap[MHL_XDC_SIZE];
> -	u8 avif[19];
> +	u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
>  	struct edid *edid;
>  	unsigned int gen2_write_burst:1;
>  	enum sii8620_mt_state mt_state;
> @@ -685,6 +690,40 @@ static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
>  	d->size = cpu_to_le16(size);
>  }
>
> +static u8 sii8620_checksum(void *ptr, int size)
> +{
> +	u8 *d = ptr, sum = 0;
> +
> +	while (size--)
> +		sum += *d++;
> +
> +	return sum;
> +}
> +
> +static void sii8620_mhl_burst_hdr_set(struct mhl3_burst_header *h,
> +	enum mhl_burst_id id)
> +{
> +	h->id = cpu_to_be16(id);
> +	h->total_entries = 1;
> +	h->sequence_index = 1;
> +}
> +
> +static void sii8620_burst_tx_bits_per_pixel_fmt(struct sii8620 *ctx, u8 fmt)
> +{
> +	struct mhl_burst_bits_per_pixel_fmt *d;
> +	const int size = sizeof(*d) + sizeof(d->desc[0]);
> +
> +	d = sii8620_burst_get_tx_buf(ctx, size);
> +	if (!d)
> +		return;
> +
> +	sii8620_mhl_burst_hdr_set(&d->hdr, MHL_BURST_ID_BITS_PER_PIXEL_FMT);
> +	d->num_entries = 1;
> +	d->desc[0].stream_id = 0;
> +	d->desc[0].pixel_format = fmt;
> +	d->hdr.checksum -= sii8620_checksum(d, size);
> +}
> +
>  static void sii8620_burst_rx_all(struct sii8620 *ctx)
>  {
>  	u8 *d = ctx->burst.rx_buf;
> @@ -949,32 +988,162 @@ static void sii8620_stop_video(struct sii8620 *ctx)
>  	sii8620_write(ctx, REG_TPI_SC, val);
>  }
>
> +static void sii8620_set_format(struct sii8620 *ctx)
> +{
> +	u8 out_fmt;
> +
> +	if (sii8620_is_mhl3(ctx)) {
> +		sii8620_setbits(ctx, REG_M3_P0CTRL,
> +				BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
> +				ctx->use_packed_pixel ? ~0 : 0);
> +	} else {
> +		if (ctx->use_packed_pixel)
> +			sii8620_write_seq_static(ctx,
> +				REG_VID_MODE, BIT_VID_MODE_M1080P,
> +				REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1,
> +				REG_MHLTX_CTL6, 0x60
> +			);
> +		else
> +			sii8620_write_seq_static(ctx,
> +				REG_VID_MODE, 0,
> +				REG_MHL_TOP_CTL, 1,
> +				REG_MHLTX_CTL6, 0xa0
> +			);
> +	}
> +
> +	if (ctx->use_packed_pixel)
> +		out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL) |
> +			BIT_TPI_OUTPUT_CSCMODE709;
> +	else
> +		out_fmt = VAL_TPI_FORMAT(RGB, FULL);
> +
> +	sii8620_write_seq(ctx,
> +		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
> +		REG_TPI_OUTPUT, out_fmt,
> +	);
> +}
> +
> +#define MHL3_VSIF_TYPE		0x81
> +#define MHL3_VSIF_VERSION	0x03
> +#define MHL3_VSIF_LENGTH	0x0f
> +#define IEEE_OUI_MHL3		0x7CA61D

Should these be in mhl.h?

Some of these seem similar to the infoframe related defs
in include/linux/hdmi.h

Do you think there should be equivalent helpers for mhl infoframes
similar to hdmi_vendor_infoframe_init
and hdmi_vendor_infoframe_pack()?

Thanks,
Archit

> +
> +static void sii8620_mhl_infoframe_init(void *ptr, int size)
> +{
> +	u8 *buf = ptr;
> +
> +	memset(buf, 0, size);
> +	buf[0] = MHL3_VSIF_TYPE;
> +	buf[1] = MHL3_VSIF_VERSION;
> +	buf[2] = MHL3_VSIF_LENGTH;
> +	buf[4] = IEEE_OUI_MHL3 & 0xff;
> +	buf[5] = (IEEE_OUI_MHL3 >> 8) & 0xff;
> +	buf[6] = (IEEE_OUI_MHL3 >> 16) & 0xff;
> +	buf[3] -= sii8620_checksum(buf, MHL3_VSIF_LENGTH);
> +}
> +
> +static void sii8620_set_infoframes(struct sii8620 *ctx)
> +{
> +	union hdmi_infoframe frm;
> +	u8 buf[31];
> +	int ret;
> +
> +	if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) {
> +		sii8620_write(ctx, REG_TPI_SC,
> +			BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
> +		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif + 3,
> +			ARRAY_SIZE(ctx->avif) - 3);
> +		sii8620_write(ctx, REG_PKT_FILTER_0,
> +			BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
> +			BIT_PKT_FILTER_0_DROP_MPEG_PKT |
> +			BIT_PKT_FILTER_0_DROP_GCP_PKT,
> +			BIT_PKT_FILTER_1_DROP_GEN_PKT);
> +		return;
> +	}
> +
> +	ret = hdmi_avi_infoframe_init(&frm.avi);
> +	frm.avi.colorspace = HDMI_COLORSPACE_YUV422;
> +	frm.avi.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
> +	frm.avi.picture_aspect = HDMI_PICTURE_ASPECT_16_9;
> +	frm.avi.colorimetry = HDMI_COLORIMETRY_ITU_709;
> +	frm.avi.video_code = ctx->video_code;
> +	if (!ret)
> +		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, ARRAY_SIZE(buf));
> +	if (ret > 0)
> +		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3);
> +	sii8620_write(ctx, REG_PKT_FILTER_0,
> +		BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
> +		BIT_PKT_FILTER_0_DROP_MPEG_PKT |
> +		BIT_PKT_FILTER_0_DROP_AVI_PKT |
> +		BIT_PKT_FILTER_0_DROP_GCP_PKT,
> +		BIT_PKT_FILTER_1_VSI_OVERRIDE_DIS |
> +		BIT_PKT_FILTER_1_DROP_GEN_PKT |
> +		BIT_PKT_FILTER_1_DROP_VSIF_PKT);
> +
> +	sii8620_write(ctx, REG_TPI_INFO_FSEL, BIT_TPI_INFO_FSEL_EN
> +		| BIT_TPI_INFO_FSEL_RPT | VAL_TPI_INFO_FSEL_VSI);
> +	sii8620_mhl_infoframe_init(buf, ARRAY_SIZE(buf));
> +	sii8620_write_buf(ctx, REG_TPI_INFO_B0, buf, ARRAY_SIZE(buf));
> +}
> +
>  static void sii8620_start_hdmi(struct sii8620 *ctx)
>  {
>  	sii8620_write_seq_static(ctx,
>  		REG_RX_HDMI_CTRL2, VAL_RX_HDMI_CTRL2_DEFVAL
>  			| BIT_RX_HDMI_CTRL2_USE_AV_MUTE,
>  		REG_VID_OVRRD, BIT_VID_OVRRD_PP_AUTO_DISABLE
> -			| BIT_VID_OVRRD_M1080P_OVRRD,
> -		REG_VID_MODE, 0,
> -		REG_MHL_TOP_CTL, 0x1,
> -		REG_MHLTX_CTL6, 0xa0,
> -		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
> -		REG_TPI_OUTPUT, VAL_TPI_FORMAT(RGB, FULL),
> -	);
> +			| BIT_VID_OVRRD_M1080P_OVRRD);
> +	sii8620_set_format(ctx);
>
> -	sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
> -			      MHL_DST_LM_CLK_MODE_NORMAL |
> -			      MHL_DST_LM_PATH_ENABLED);
> -
> -	sii8620_set_auto_zone(ctx);
> +	if (!sii8620_is_mhl3(ctx)) {
> +		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
> +			MHL_DST_LM_CLK_MODE_NORMAL | MHL_DST_LM_PATH_ENABLED);
> +		sii8620_set_auto_zone(ctx);
> +	} else {
> +		static const struct {
> +			int max_clk;
> +			u8 zone;
> +			u8 link_rate;
> +			u8 rrp_decode;
> +		} clk_spec[] = {
> +			{ 150000, VAL_TX_ZONE_CTL3_TX_ZONE_1_5GBPS,
> +			  MHL_XDS_LINK_RATE_1_5_GBPS, 0x38 },
> +			{ 300000, VAL_TX_ZONE_CTL3_TX_ZONE_3GBPS,
> +			  MHL_XDS_LINK_RATE_3_0_GBPS, 0x40 },
> +			{ 600000, VAL_TX_ZONE_CTL3_TX_ZONE_6GBPS,
> +			  MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 },
> +		};
> +		u8 p0_ctrl = BIT_M3_P0CTRL_MHL3_P0_PORT_EN;
> +		int clk = ctx->pixel_clock * (ctx->use_packed_pixel ? 2 : 3);
> +		int i;
> +
> +		for (i = 0; i < ARRAY_SIZE(clk_spec); ++i)
> +			if (clk < clk_spec[i].max_clk)
> +				break;
>
> -	sii8620_write(ctx, REG_TPI_SC, BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
> +		if (100 * clk >= 98 * clk_spec[i].max_clk)
> +			p0_ctrl |= BIT_M3_P0CTRL_MHL3_P0_UNLIMIT_EN;
>
> -	sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif,
> -			  ARRAY_SIZE(ctx->avif));
> +		sii8620_burst_tx_bits_per_pixel_fmt(ctx, ctx->use_packed_pixel);
> +		sii8620_burst_send(ctx);
> +		sii8620_write_seq(ctx,
> +			REG_MHL_DP_CTL0, 0xf0,
> +			REG_MHL3_TX_ZONE_CTL, clk_spec[i].zone);
> +		sii8620_setbits(ctx, REG_M3_P0CTRL,
> +			BIT_M3_P0CTRL_MHL3_P0_PORT_EN
> +			| BIT_M3_P0CTRL_MHL3_P0_UNLIMIT_EN, p0_ctrl);
> +		sii8620_setbits(ctx, REG_M3_POSTM, MSK_M3_POSTM_RRP_DECODE,
> +			clk_spec[i].rrp_decode);
> +		sii8620_write_seq_static(ctx,
> +			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE
> +				| BIT_M3_CTRL_H2M_SWRST,
> +			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE
> +		);
> +		sii8620_mt_write_stat(ctx, MHL_XDS_REG(AVLINK_MODE_CONTROL),
> +			clk_spec[i].link_rate);
> +	}
>
> -	sii8620_write(ctx, REG_PKT_FILTER_0, 0xa1, 0x2);
> +	sii8620_set_infoframes(ctx);
>  }
>
>  static void sii8620_start_video(struct sii8620 *ctx)
> @@ -1834,22 +2003,44 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge,
>  			       struct drm_display_mode *adjusted_mode)
>  {
>  	struct sii8620 *ctx = bridge_to_sii8620(bridge);
> -	bool ret = false;
> -	int max_clock = 74250;
> -
> -	mutex_lock(&ctx->lock);
> -
> -	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> -		goto out;
> +	int max_lclk;
> +	bool ret = true;
>
> -	if (ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL)
> -		max_clock = 300000;
> +	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
> +		return false;
>
> -	ret = mode->clock <= max_clock;
> +	mutex_lock(&ctx->lock);
>
> -out:
> +	max_lclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : MHL1_MAX_LCLK;
> +	if (max_lclk > 3 * adjusted_mode->clock) {
> +		ctx->use_packed_pixel = 0;
> +		goto end;
> +	}
> +	if ((ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL) &&
> +	    max_lclk > 2 * adjusted_mode->clock) {
> +		ctx->use_packed_pixel = 1;
> +		goto end;
> +	}
> +	ret = false;
> +end:
> +	if (ret) {
> +		u8 vic = drm_match_cea_mode(adjusted_mode);
> +
> +		if (!vic) {
> +			union hdmi_infoframe frm;
> +			u8 mhl_vic[] = { 0, 95, 94, 93, 98 };
> +
> +			drm_hdmi_vendor_infoframe_from_display_mode(
> +				&frm.vendor.hdmi, adjusted_mode);
> +			vic = frm.vendor.hdmi.vic;
> +			if (vic >= ARRAY_SIZE(mhl_vic))
> +				vic = 0;
> +			vic = mhl_vic[vic];
> +		}
> +		ctx->video_code = vic;
> +		ctx->pixel_clock = adjusted_mode->clock;
> +	}
>  	mutex_unlock(&ctx->lock);
> -
>  	return ret;
>  }
>
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
> index f7bfbc3..aefae67 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.h
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.h
> @@ -1084,10 +1084,17 @@
>
>  /* TPI Info Frame Select, default value: 0x00 */
>  #define REG_TPI_INFO_FSEL			0x06bf
> -#define BIT_TPI_INFO_FSEL_TPI_INFO_EN		BIT(7)
> -#define BIT_TPI_INFO_FSEL_TPI_INFO_RPT		BIT(6)
> -#define BIT_TPI_INFO_FSEL_TPI_INFO_READ_FLAG	BIT(5)
> -#define MSK_TPI_INFO_FSEL_TPI_INFO_SEL		0x07
> +#define BIT_TPI_INFO_FSEL_EN			BIT(7)
> +#define BIT_TPI_INFO_FSEL_RPT			BIT(6)
> +#define BIT_TPI_INFO_FSEL_READ_FLAG		BIT(5)
> +#define MSK_TPI_INFO_FSEL_PKT			0x07
> +#define VAL_TPI_INFO_FSEL_AVI			0x00
> +#define VAL_TPI_INFO_FSEL_SPD			0x01
> +#define VAL_TPI_INFO_FSEL_AUD			0x02
> +#define VAL_TPI_INFO_FSEL_MPG			0x03
> +#define VAL_TPI_INFO_FSEL_GEN			0x04
> +#define VAL_TPI_INFO_FSEL_GEN2			0x05
> +#define VAL_TPI_INFO_FSEL_VSI			0x06
>
>  /* TPI Info Byte #0, default value: 0x00 */
>  #define REG_TPI_INFO_B0				0x06c0
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 04/24] drm/bridge/sii8620: add continuations to messages
  2017-01-23  8:31       ` Archit Taneja
@ 2017-01-23 10:33         ` Andrzej Hajda
  2017-01-24  7:57           ` Archit Taneja
       [not found]         ` <CGME20170126134315eucas1p1db71a5e2f14fd93283d14a2da4f05611@eucas1p1.samsung.com>
  1 sibling, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-23 10:33 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

On 23.01.2017 09:31, Archit Taneja wrote:
>
> On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
>> Due to asynchronous nature of MHL flow of execution is dispersed. Logical
>> continuation of some actions happens after response of peer, i.e in interrupt
>> handler. To simplify coding continuation mechanism has been added - it is now
>> possible to provide continuation callback, which will be called after peer
>> responds to given action.
> Could you wrap this to 75 chars?

OK

>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> ---
>>  drivers/gpu/drm/bridge/sil-sii8620.c | 20 ++++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
>> index 75867c0..cde0074 100644
>> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
>> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
>> @@ -78,12 +78,15 @@ struct sii8620_mt_msg;
>>  typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
>>  				  struct sii8620_mt_msg *msg);
>>
>> +typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
>> +
>>  struct sii8620_mt_msg {
>>  	struct list_head node;
>>  	u8 reg[4];
>>  	u8 ret;
>>  	sii8620_mt_msg_cb send;
>>  	sii8620_mt_msg_cb recv;
>> +	sii8620_cb continuation;
>>  };
>>
>>  static const u8 sii8620_i2c_page[] = {
>> @@ -258,6 +261,8 @@ static void sii8620_mt_work(struct sii8620 *ctx)
>>  				       node);
>>  		if (msg->recv)
>>  			msg->recv(ctx, msg);
>> +		if (msg->continuation)
>> +			msg->continuation(ctx, msg->ret);
> I was wondering if instead of executing the continuation via a callback,
> would it make sense to insert them as a new message instead?
>
> I don't have the complete context of this, so feel free to ignore the suggestion
> if doesn't make sense.

My assumption was that continuation should be tied to the message it was
attached to - ie it should be called after response for the message and
it should be called with the result of the response.
If we assume messages are fully serialized (as it is now) it could be
done as you suggested, but I prefer to leave possibility to de-serialize
message queue in the future.

Regards
Andrzej

>
> Thanks,
> Archit
>
>>  		list_del(&msg->node);
>>  		kfree(msg);
>>  	}
>> @@ -310,6 +315,21 @@ static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx)
>>  	return msg;
>>  }
>>
>> +static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont)
>> +{
>> +	struct sii8620_mt_msg *msg;
>> +
>> +	if (ctx->error)
>> +		return;
>> +
>> +	if (list_empty(&ctx->mt_queue)) {
>> +		ctx->error = -EINVAL;
>> +		return;
>> +	}
>> +	msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node);
>> +	msg->continuation = cont;
>> +}
>> +
>>  static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2)
>>  {
>>  	struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);
>>

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

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

* Re: [PATCH 07/24] drm/bridge/sii8620: add support for burst eMSC transmissions
  2017-01-23  8:20       ` Archit Taneja
@ 2017-01-23 10:38         ` Andrzej Hajda
       [not found]         ` <CGME20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc@eucas1p2.samsung.com>
  1 sibling, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-23 10:38 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

On 23.01.2017 09:20, Archit Taneja wrote:
(...)
>>  static void sii8620_fetch_edid(struct sii8620 *ctx)
>>  {
>>  	u8 lm_ddc, ddc_cmd, int3, cbus;
>> @@ -1041,7 +1181,7 @@ static int sii8620_wait_for_fsm_state(struct sii8620 *ctx, u8 state)
>>
>>  		if ((s & MSK_COC_STAT_0_FSM_STATE) == state)
>>  			return 0;
>> -		if (s & BIT_COC_STAT_0_PLL_LOCKED)
>> +		if (!(s & BIT_COC_STAT_0_PLL_LOCKED))
> Should this be a part of patch #5?

Yes, of course, it is just fix for patch #5.

>
>>  			return -EBUSY;
>>  		usleep_range(4000, 6000);
>>  	}
>> @@ -1417,6 +1557,19 @@ static void sii8620_irq_coc(struct sii8620 *ctx)
>>  {
>>  	u8 stat = sii8620_readb(ctx, REG_COC_INTR);
>>
>> +	if (stat & BIT_COC_CALIBRATION_DONE) {
>> +		u8 cstat = sii8620_readb(ctx, REG_COC_STAT_0);
>> +
>> +		cstat &= BIT_COC_STAT_0_PLL_LOCKED | MSK_COC_STAT_0_FSM_STATE;
>> +		if (cstat == (BIT_COC_STAT_0_PLL_LOCKED | 0x02)) {
>> +			sii8620_write_seq_static(ctx,
>> +				REG_COC_CTLB, 0,
>> +				REG_TRXINTMH, BIT_TDM_INTR_SYNC_DATA
>> +					      | BIT_TDM_INTR_SYNC_WAIT
>> +			);
>> +		}
>> +	}
>> +
>>  	sii8620_write(ctx, REG_COC_INTR, stat);
>>  }
>>
>> @@ -1507,6 +1660,41 @@ static void sii8620_irq_infr(struct sii8620 *ctx)
>>  		sii8620_start_video(ctx);
>>  }
>>
>> +static void sii8620_irq_tdm(struct sii8620 *ctx)
>> +{
>> +	u8 stat = sii8620_readb(ctx, REG_TRXINTH);
>> +	u8 tdm = sii8620_readb(ctx, REG_TRXSTA2);
>> +
>> +	if ((tdm & MSK_TDM_SYNCHRONIZED) == VAL_TDM_SYNCHRONIZED) {
>> +		ctx->mode = CM_ECBUS_S;
>> +		ctx->burst.rx_ack = 0;
>> +		ctx->burst.r_size = SII8620_BURST_BUF_LEN;
>> +		sii8620_burst_tx_rbuf_info(ctx, SII8620_BURST_BUF_LEN);
>> +		sii8620_mt_read_devcap(ctx, true);
>> +	} else {
>> +		sii8620_write_seq_static(ctx,
>> +			REG_MHL_PLL_CTL2, 0,
>> +			REG_MHL_PLL_CTL2, BIT_MHL_PLL_CTL2_CLKDETECT_EN
>> +		);
>> +	}
>> +
>> +	sii8620_write(ctx, REG_TRXINTH, stat);
>> +}
>> +
>> +static void sii8620_irq_block(struct sii8620 *ctx)
>> +{
>> +	u8 stat = sii8620_readb(ctx, REG_EMSCINTR);
>> +
>> +	if (stat & BIT_EMSCINTR_SPI_DVLD) {
>> +		u8 bstat = sii8620_readb(ctx, REG_SPIBURSTSTAT);
>> +
>> +		if (bstat & BIT_SPIBURSTSTAT_EMSC_NORMAL_MODE)
>> +			sii8620_burst_receive(ctx);
>> +	}
>> +
>> +	sii8620_write(ctx, REG_EMSCINTR, stat);
>> +}
>> +
>>  /* endian agnostic, non-volatile version of test_bit */
>>  static bool sii8620_test_bit(unsigned int nr, const u8 *addr)
>>  {
>> @@ -1522,8 +1710,10 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
>>  		{ BIT_FAST_INTR_STAT_DISC, sii8620_irq_disc },
>>  		{ BIT_FAST_INTR_STAT_G2WB, sii8620_irq_g2wb },
>>  		{ BIT_FAST_INTR_STAT_COC, sii8620_irq_coc },
>> +		{ BIT_FAST_INTR_STAT_TDM, sii8620_irq_tdm },
>>  		{ BIT_FAST_INTR_STAT_MSC, sii8620_irq_msc },
>>  		{ BIT_FAST_INTR_STAT_MERR, sii8620_irq_merr },
>> +		{ BIT_FAST_INTR_STAT_BLOCK, sii8620_irq_block },
>>  		{ BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid },
>>  		{ BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt },
>>  		{ BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr },
>> @@ -1539,7 +1729,9 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
>>  		if (sii8620_test_bit(irq_vec[i].bit, stats))
>>  			irq_vec[i].handler(ctx);
>>
>> +	sii8620_burst_rx_all(ctx);
>>  	sii8620_mt_work(ctx);
>> +	sii8620_burst_send(ctx);
>>
>>  	ret = sii8620_clear_error(ctx);
>>  	if (ret) {
>> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
>> index 3ee4e7e..f7bfbc3 100644
>> --- a/drivers/gpu/drm/bridge/sil-sii8620.h
>> +++ b/drivers/gpu/drm/bridge/sil-sii8620.h
>> @@ -403,12 +403,16 @@
>>
>>  /* TDM RX Status 2nd, default value: 0x00 */
>>  #define REG_TRXSTA2				0x015c
>> +#define MSK_TDM_SYNCHRONIZED			0xC0
> Would be nice to not have the hex digits in caps here.


OK, this one somehow sneaked out :)

Regards
Andrzej

>
> Thanks,
> Archit
>
>> +#define VAL_TDM_SYNCHRONIZED			0x80
>>
>>  /* TDM RX INT Low, default value: 0x00 */
>>  #define REG_TRXINTL				0x0163
>>
>>  /* TDM RX INT High, default value: 0x00 */
>>  #define REG_TRXINTH				0x0164
>> +#define BIT_TDM_INTR_SYNC_DATA			BIT(0)
>> +#define BIT_TDM_INTR_SYNC_WAIT			BIT(1)
>>
>>  /* TDM RX INTMASK High, default value: 0x00 */
>>  #define REG_TRXINTMH				0x0166
>>

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

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

* Re: [PATCH 19/24] drm/bridge/sii8620: rewrite hdmi start sequence
  2017-01-23  9:17       ` Archit Taneja
@ 2017-01-23 11:12         ` Andrzej Hajda
  2017-01-24  8:09           ` Archit Taneja
  0 siblings, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-23 11:12 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

On 23.01.2017 10:17, Archit Taneja wrote:
>
> On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
>> MHL3 protocol requires registry adjustments depending on chosen video mode.
>> Necessary information is gathered in mode_fixup callback. In case of HDMI
>> video modes driver should also send special AVI and MHL infoframes.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> ---
>>  drivers/gpu/drm/bridge/sil-sii8620.c | 249 +++++++++++++++++++++++++++++++----
>>  drivers/gpu/drm/bridge/sil-sii8620.h |  15 ++-
>>  2 files changed, 231 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
>> index 1c76905..2c7b5b9 100644
>> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
>> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
>> @@ -32,6 +32,8 @@
>>
>>  #define SII8620_BURST_BUF_LEN 288
>>  #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
>> +#define MHL1_MAX_LCLK 225000
>> +#define MHL3_MAX_LCLK 600000
>>
>>  enum sii8620_mode {
>>  	CM_DISCONNECTED,
>> @@ -62,6 +64,9 @@ struct sii8620 {
>>  	struct regulator_bulk_data supplies[2];
>>  	struct mutex lock; /* context lock, protects fields below */
>>  	int error;
>> +	int pixel_clock;
>> +	unsigned int use_packed_pixel:1;
>> +	int video_code;
>>  	enum sii8620_mode mode;
>>  	enum sii8620_sink_type sink_type;
>>  	u8 cbus_status;
>> @@ -69,7 +74,7 @@ struct sii8620 {
>>  	u8 xstat[MHL_XDS_SIZE];
>>  	u8 devcap[MHL_DCAP_SIZE];
>>  	u8 xdevcap[MHL_XDC_SIZE];
>> -	u8 avif[19];
>> +	u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
>>  	struct edid *edid;
>>  	unsigned int gen2_write_burst:1;
>>  	enum sii8620_mt_state mt_state;
>> @@ -685,6 +690,40 @@ static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
>>  	d->size = cpu_to_le16(size);
>>  }
>>
>> +static u8 sii8620_checksum(void *ptr, int size)
>> +{
>> +	u8 *d = ptr, sum = 0;
>> +
>> +	while (size--)
>> +		sum += *d++;
>> +
>> +	return sum;
>> +}
>> +
>> +static void sii8620_mhl_burst_hdr_set(struct mhl3_burst_header *h,
>> +	enum mhl_burst_id id)
>> +{
>> +	h->id = cpu_to_be16(id);
>> +	h->total_entries = 1;
>> +	h->sequence_index = 1;
>> +}
>> +
>> +static void sii8620_burst_tx_bits_per_pixel_fmt(struct sii8620 *ctx, u8 fmt)
>> +{
>> +	struct mhl_burst_bits_per_pixel_fmt *d;
>> +	const int size = sizeof(*d) + sizeof(d->desc[0]);
>> +
>> +	d = sii8620_burst_get_tx_buf(ctx, size);
>> +	if (!d)
>> +		return;
>> +
>> +	sii8620_mhl_burst_hdr_set(&d->hdr, MHL_BURST_ID_BITS_PER_PIXEL_FMT);
>> +	d->num_entries = 1;
>> +	d->desc[0].stream_id = 0;
>> +	d->desc[0].pixel_format = fmt;
>> +	d->hdr.checksum -= sii8620_checksum(d, size);
>> +}
>> +
>>  static void sii8620_burst_rx_all(struct sii8620 *ctx)
>>  {
>>  	u8 *d = ctx->burst.rx_buf;
>> @@ -949,32 +988,162 @@ static void sii8620_stop_video(struct sii8620 *ctx)
>>  	sii8620_write(ctx, REG_TPI_SC, val);
>>  }
>>
>> +static void sii8620_set_format(struct sii8620 *ctx)
>> +{
>> +	u8 out_fmt;
>> +
>> +	if (sii8620_is_mhl3(ctx)) {
>> +		sii8620_setbits(ctx, REG_M3_P0CTRL,
>> +				BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
>> +				ctx->use_packed_pixel ? ~0 : 0);
>> +	} else {
>> +		if (ctx->use_packed_pixel)
>> +			sii8620_write_seq_static(ctx,
>> +				REG_VID_MODE, BIT_VID_MODE_M1080P,
>> +				REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1,
>> +				REG_MHLTX_CTL6, 0x60
>> +			);
>> +		else
>> +			sii8620_write_seq_static(ctx,
>> +				REG_VID_MODE, 0,
>> +				REG_MHL_TOP_CTL, 1,
>> +				REG_MHLTX_CTL6, 0xa0
>> +			);
>> +	}
>> +
>> +	if (ctx->use_packed_pixel)
>> +		out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL) |
>> +			BIT_TPI_OUTPUT_CSCMODE709;
>> +	else
>> +		out_fmt = VAL_TPI_FORMAT(RGB, FULL);
>> +
>> +	sii8620_write_seq(ctx,
>> +		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
>> +		REG_TPI_OUTPUT, out_fmt,
>> +	);
>> +}
>> +
>> +#define MHL3_VSIF_TYPE		0x81
>> +#define MHL3_VSIF_VERSION	0x03
>> +#define MHL3_VSIF_LENGTH	0x0f
>> +#define IEEE_OUI_MHL3		0x7CA61D
> Should these be in mhl.h?
>
> Some of these seem similar to the infoframe related defs
> in include/linux/hdmi.h
>
> Do you think there should be equivalent helpers for mhl infoframes
> similar to hdmi_vendor_infoframe_init
> and hdmi_vendor_infoframe_pack()?

Answer is yes, IMHO, for both questions, but since the only
documentation I have access to is vendor code I am little bit hesitant
in pushing such things into mhl header.
I am not sure if I can properly describe all fields of MHL3 VSIF
infoframe, but beside this I have no objections :)
One thing is in case of implementing mhl infoframe helpers: where to put
them to, ie which file?

Regards
Andrzej

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

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

* Re: [PATCH 04/24] drm/bridge/sii8620: add continuations to messages
  2017-01-23 10:33         ` Andrzej Hajda
@ 2017-01-24  7:57           ` Archit Taneja
  0 siblings, 0 replies; 42+ messages in thread
From: Archit Taneja @ 2017-01-24  7:57 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/23/2017 04:03 PM, Andrzej Hajda wrote:
> On 23.01.2017 09:31, Archit Taneja wrote:
>>
>> On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
>>> Due to asynchronous nature of MHL flow of execution is dispersed. Logical
>>> continuation of some actions happens after response of peer, i.e in interrupt
>>> handler. To simplify coding continuation mechanism has been added - it is now
>>> possible to provide continuation callback, which will be called after peer
>>> responds to given action.
>> Could you wrap this to 75 chars?
>
> OK
>
>>
>>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>>> ---
>>>  drivers/gpu/drm/bridge/sil-sii8620.c | 20 ++++++++++++++++++++
>>>  1 file changed, 20 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
>>> index 75867c0..cde0074 100644
>>> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
>>> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
>>> @@ -78,12 +78,15 @@ struct sii8620_mt_msg;
>>>  typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
>>>  				  struct sii8620_mt_msg *msg);
>>>
>>> +typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
>>> +
>>>  struct sii8620_mt_msg {
>>>  	struct list_head node;
>>>  	u8 reg[4];
>>>  	u8 ret;
>>>  	sii8620_mt_msg_cb send;
>>>  	sii8620_mt_msg_cb recv;
>>> +	sii8620_cb continuation;
>>>  };
>>>
>>>  static const u8 sii8620_i2c_page[] = {
>>> @@ -258,6 +261,8 @@ static void sii8620_mt_work(struct sii8620 *ctx)
>>>  				       node);
>>>  		if (msg->recv)
>>>  			msg->recv(ctx, msg);
>>> +		if (msg->continuation)
>>> +			msg->continuation(ctx, msg->ret);
>> I was wondering if instead of executing the continuation via a callback,
>> would it make sense to insert them as a new message instead?
>>
>> I don't have the complete context of this, so feel free to ignore the suggestion
>> if doesn't make sense.
>
> My assumption was that continuation should be tied to the message it was
> attached to - ie it should be called after response for the message and
> it should be called with the result of the response.
> If we assume messages are fully serialized (as it is now) it could be
> done as you suggested, but I prefer to leave possibility to de-serialize
> message queue in the future.

Sure. Let's leave it as is.

Archit

>
> Regards
> Andrzej
>
>>
>> Thanks,
>> Archit
>>
>>>  		list_del(&msg->node);
>>>  		kfree(msg);
>>>  	}
>>> @@ -310,6 +315,21 @@ static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx)
>>>  	return msg;
>>>  }
>>>
>>> +static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont)
>>> +{
>>> +	struct sii8620_mt_msg *msg;
>>> +
>>> +	if (ctx->error)
>>> +		return;
>>> +
>>> +	if (list_empty(&ctx->mt_queue)) {
>>> +		ctx->error = -EINVAL;
>>> +		return;
>>> +	}
>>> +	msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node);
>>> +	msg->continuation = cont;
>>> +}
>>> +
>>>  static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2)
>>>  {
>>>  	struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);
>>>
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 19/24] drm/bridge/sii8620: rewrite hdmi start sequence
  2017-01-23 11:12         ` Andrzej Hajda
@ 2017-01-24  8:09           ` Archit Taneja
       [not found]             ` <CGME20170126135053eucas1p2b1f31992f4c68a3946aa425f00271e5d@eucas1p2.samsung.com>
  0 siblings, 1 reply; 42+ messages in thread
From: Archit Taneja @ 2017-01-24  8:09 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/23/2017 04:42 PM, Andrzej Hajda wrote:
> On 23.01.2017 10:17, Archit Taneja wrote:
>>
>> On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
>>> MHL3 protocol requires registry adjustments depending on chosen video mode.
>>> Necessary information is gathered in mode_fixup callback. In case of HDMI
>>> video modes driver should also send special AVI and MHL infoframes.
>>>
>>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>>> ---
>>>  drivers/gpu/drm/bridge/sil-sii8620.c | 249 +++++++++++++++++++++++++++++++----
>>>  drivers/gpu/drm/bridge/sil-sii8620.h |  15 ++-
>>>  2 files changed, 231 insertions(+), 33 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
>>> index 1c76905..2c7b5b9 100644
>>> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
>>> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
>>> @@ -32,6 +32,8 @@
>>>
>>>  #define SII8620_BURST_BUF_LEN 288
>>>  #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
>>> +#define MHL1_MAX_LCLK 225000
>>> +#define MHL3_MAX_LCLK 600000
>>>
>>>  enum sii8620_mode {
>>>  	CM_DISCONNECTED,
>>> @@ -62,6 +64,9 @@ struct sii8620 {
>>>  	struct regulator_bulk_data supplies[2];
>>>  	struct mutex lock; /* context lock, protects fields below */
>>>  	int error;
>>> +	int pixel_clock;
>>> +	unsigned int use_packed_pixel:1;
>>> +	int video_code;
>>>  	enum sii8620_mode mode;
>>>  	enum sii8620_sink_type sink_type;
>>>  	u8 cbus_status;
>>> @@ -69,7 +74,7 @@ struct sii8620 {
>>>  	u8 xstat[MHL_XDS_SIZE];
>>>  	u8 devcap[MHL_DCAP_SIZE];
>>>  	u8 xdevcap[MHL_XDC_SIZE];
>>> -	u8 avif[19];
>>> +	u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
>>>  	struct edid *edid;
>>>  	unsigned int gen2_write_burst:1;
>>>  	enum sii8620_mt_state mt_state;
>>> @@ -685,6 +690,40 @@ static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
>>>  	d->size = cpu_to_le16(size);
>>>  }
>>>
>>> +static u8 sii8620_checksum(void *ptr, int size)
>>> +{
>>> +	u8 *d = ptr, sum = 0;
>>> +
>>> +	while (size--)
>>> +		sum += *d++;
>>> +
>>> +	return sum;
>>> +}
>>> +
>>> +static void sii8620_mhl_burst_hdr_set(struct mhl3_burst_header *h,
>>> +	enum mhl_burst_id id)
>>> +{
>>> +	h->id = cpu_to_be16(id);
>>> +	h->total_entries = 1;
>>> +	h->sequence_index = 1;
>>> +}
>>> +
>>> +static void sii8620_burst_tx_bits_per_pixel_fmt(struct sii8620 *ctx, u8 fmt)
>>> +{
>>> +	struct mhl_burst_bits_per_pixel_fmt *d;
>>> +	const int size = sizeof(*d) + sizeof(d->desc[0]);
>>> +
>>> +	d = sii8620_burst_get_tx_buf(ctx, size);
>>> +	if (!d)
>>> +		return;
>>> +
>>> +	sii8620_mhl_burst_hdr_set(&d->hdr, MHL_BURST_ID_BITS_PER_PIXEL_FMT);
>>> +	d->num_entries = 1;
>>> +	d->desc[0].stream_id = 0;
>>> +	d->desc[0].pixel_format = fmt;
>>> +	d->hdr.checksum -= sii8620_checksum(d, size);
>>> +}
>>> +
>>>  static void sii8620_burst_rx_all(struct sii8620 *ctx)
>>>  {
>>>  	u8 *d = ctx->burst.rx_buf;
>>> @@ -949,32 +988,162 @@ static void sii8620_stop_video(struct sii8620 *ctx)
>>>  	sii8620_write(ctx, REG_TPI_SC, val);
>>>  }
>>>
>>> +static void sii8620_set_format(struct sii8620 *ctx)
>>> +{
>>> +	u8 out_fmt;
>>> +
>>> +	if (sii8620_is_mhl3(ctx)) {
>>> +		sii8620_setbits(ctx, REG_M3_P0CTRL,
>>> +				BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
>>> +				ctx->use_packed_pixel ? ~0 : 0);
>>> +	} else {
>>> +		if (ctx->use_packed_pixel)
>>> +			sii8620_write_seq_static(ctx,
>>> +				REG_VID_MODE, BIT_VID_MODE_M1080P,
>>> +				REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1,
>>> +				REG_MHLTX_CTL6, 0x60
>>> +			);
>>> +		else
>>> +			sii8620_write_seq_static(ctx,
>>> +				REG_VID_MODE, 0,
>>> +				REG_MHL_TOP_CTL, 1,
>>> +				REG_MHLTX_CTL6, 0xa0
>>> +			);
>>> +	}
>>> +
>>> +	if (ctx->use_packed_pixel)
>>> +		out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL) |
>>> +			BIT_TPI_OUTPUT_CSCMODE709;
>>> +	else
>>> +		out_fmt = VAL_TPI_FORMAT(RGB, FULL);
>>> +
>>> +	sii8620_write_seq(ctx,
>>> +		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
>>> +		REG_TPI_OUTPUT, out_fmt,
>>> +	);
>>> +}
>>> +
>>> +#define MHL3_VSIF_TYPE		0x81
>>> +#define MHL3_VSIF_VERSION	0x03
>>> +#define MHL3_VSIF_LENGTH	0x0f
>>> +#define IEEE_OUI_MHL3		0x7CA61D
>> Should these be in mhl.h?
>>
>> Some of these seem similar to the infoframe related defs
>> in include/linux/hdmi.h
>>
>> Do you think there should be equivalent helpers for mhl infoframes
>> similar to hdmi_vendor_infoframe_init
>> and hdmi_vendor_infoframe_pack()?
>
> Answer is yes, IMHO, for both questions, but since the only
> documentation I have access to is vendor code I am little bit hesitant
> in pushing such things into mhl header.
> I am not sure if I can properly describe all fields of MHL3 VSIF
> infoframe, but beside this I have no objections :)

I think it should be okay to move these in mhl.h. I think we should drop
the version macro, though. The hdmi helpers don't created macros for
the infoframe numbers either.

> One thing is in case of implementing mhl infoframe helpers: where to put
> them to, ie which file?

I guess we could eventually have a new mhl helper, similar to
drivers/video/hdmi.c. The mhl helper probably could sit in
the bridge folder for now, since I have only heard of MHL
being implemented as an external bridge chip.

For now, you could maybe add a comment saying that these funcs can
potentially be helpers, and give them non-sil8620 name.

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 17/24] drm/bridge/sii8620: split EDID read and write code
  2017-01-20  7:38     ` [PATCH 17/24] drm/bridge/sii8620: split EDID read and write code Andrzej Hajda
@ 2017-01-24 10:31       ` Archit Taneja
  2017-01-24 11:39         ` Andrzej Hajda
  0 siblings, 1 reply; 42+ messages in thread
From: Archit Taneja @ 2017-01-24 10:31 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
> MHL3 requires that after reading EDID from the sink source should ask
> peer for features. To make both protocols happy the patch splits the code
> accordingly.

I was wondering about the EDID code in the driver, what does it exactly
do with the EDID? We don't seem to be populating connector modes with it.
I saw a func called sii8620_set_upstream_edid(), but didn't understand
what it does.

Archit

>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/bridge/sil-sii8620.c | 31 +++++++++++++++++++++++++++----
>  1 file changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 6ef1a4d..d0e6dc3 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -482,6 +482,13 @@ static void sii8620_sink_detected(struct sii8620 *ctx, int ret)
>
>  	dev_info(dev, "detected sink(type: %s): %s\n",
>  		 sink_str[ctx->sink_type], sink_name);
> +}
> +
> +static void sii8620_edid_read(struct sii8620 *ctx, int ret)
> +{
> +	if (ret < 0)
> +		return;
> +
>  	sii8620_set_upstream_edid(ctx);
>  	sii8620_enable_hpd(ctx);
>  }
> @@ -787,12 +794,12 @@ static void sii8620_fetch_edid(struct sii8620 *ctx)
>  				edid = new_edid;
>  			}
>  		}
> -
> -		if (fetched + FETCH_SIZE == edid_len)
> -			sii8620_write(ctx, REG_INTR3, int3);
>  	}
>
> -	sii8620_write(ctx, REG_LM_DDC, lm_ddc);
> +	sii8620_write_seq(ctx,
> +		REG_INTR3_MASK, BIT_DDC_CMD_DONE,
> +		REG_LM_DDC, lm_ddc
> +	);
>
>  end:
>  	kfree(ctx->edid);
> @@ -1706,6 +1713,21 @@ static void sii8620_irq_block(struct sii8620 *ctx)
>  	sii8620_write(ctx, REG_EMSCINTR, stat);
>  }
>
> +static void sii8620_irq_ddc(struct sii8620 *ctx)
> +{
> +	u8 stat = sii8620_readb(ctx, REG_INTR3);
> +
> +	if (stat & BIT_DDC_CMD_DONE) {
> +		sii8620_write(ctx, REG_INTR3_MASK, 0);
> +		if (sii8620_is_mhl3(ctx))
> +			sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE),
> +					   MHL_INT_RC_FEAT_REQ);
> +		else
> +			sii8620_edid_read(ctx, 0);
> +	}
> +	sii8620_write(ctx, REG_INTR3, stat);
> +}
> +
>  /* endian agnostic, non-volatile version of test_bit */
>  static bool sii8620_test_bit(unsigned int nr, const u8 *addr)
>  {
> @@ -1726,6 +1748,7 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
>  		{ BIT_FAST_INTR_STAT_MERR, sii8620_irq_merr },
>  		{ BIT_FAST_INTR_STAT_BLOCK, sii8620_irq_block },
>  		{ BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid },
> +		{ BIT_FAST_INTR_STAT_DDC, sii8620_irq_ddc },
>  		{ BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt },
>  		{ BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr },
>  	};
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 17/24] drm/bridge/sii8620: split EDID read and write code
  2017-01-24 10:31       ` Archit Taneja
@ 2017-01-24 11:39         ` Andrzej Hajda
  2017-01-25  9:48           ` Archit Taneja
  0 siblings, 1 reply; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-24 11:39 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

On 24.01.2017 11:31, Archit Taneja wrote:
>
> On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
>> MHL3 requires that after reading EDID from the sink source should ask
>> peer for features. To make both protocols happy the patch splits the code
>> accordingly.
> I was wondering about the EDID code in the driver, what does it exactly
> do with the EDID? We don't seem to be populating connector modes with it.
> I saw a func called sii8620_set_upstream_edid(), but didn't understand
> what it does.

MHL reads EDID from TV (or MHL dongle) using MHL protocol and publish it
upstream (for example to exynos_hdmi on tm2 devices) via i2c bus.
With some modifications SiI8620 could act as connector and do mode
population itself, it would require modification of exynos_hdmi, and the
main drawback is that modes unsupported by exynos_hdmi would not be
filtered out (as mode filtering is done in connector).

Regards
Andrzej
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 17/24] drm/bridge/sii8620: split EDID read and write code
  2017-01-24 11:39         ` Andrzej Hajda
@ 2017-01-25  9:48           ` Archit Taneja
  0 siblings, 0 replies; 42+ messages in thread
From: Archit Taneja @ 2017-01-25  9:48 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/24/2017 05:09 PM, Andrzej Hajda wrote:
> On 24.01.2017 11:31, Archit Taneja wrote:
>>
>> On 01/20/2017 01:08 PM, Andrzej Hajda wrote:
>>> MHL3 requires that after reading EDID from the sink source should ask
>>> peer for features. To make both protocols happy the patch splits the code
>>> accordingly.
>> I was wondering about the EDID code in the driver, what does it exactly
>> do with the EDID? We don't seem to be populating connector modes with it.
>> I saw a func called sii8620_set_upstream_edid(), but didn't understand
>> what it does.
>
> MHL reads EDID from TV (or MHL dongle) using MHL protocol and publish it
> upstream (for example to exynos_hdmi on tm2 devices) via i2c bus.

Oh okay. So, the MHL writes it into some sort of flash, which exynos_hdmi
can access via an i2c master?


> With some modifications SiI8620 could act as connector and do mode
> population itself, it would require modification of exynos_hdmi, and the
> main drawback is that modes unsupported by exynos_hdmi would not be
> filtered out (as mode filtering is done in connector).

Yeah, I guess if exynos_hdmi as a drm_encoder wouldn't be able to drop
modes. The best it could do is return an error in mode_fixup.

Anyway, since there seems to be only one kms user for the sil8620
driver, I think we can leave it for later.

Btw, the patchset looks fine to me. It'd be great if you could have
slightly more descriptive commit messages for some of the patches.

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 04/25] drm/bridge/sii8620: add continuations to messages
       [not found]         ` <CGME20170126134315eucas1p1db71a5e2f14fd93283d14a2da4f05611@eucas1p1.samsung.com>
@ 2017-01-26 13:43           ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-26 13:43 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Due to asynchronous nature of MHL flow of execution is dispersed.
Logical continuation of some actions happens after response of peer,
i.e in interrupt handler. To simplify coding continuation mechanism
has been added - it is now possible to provide continuation callback,
which will be called after peer responds to given action.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 75867c0..cde0074 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -78,12 +78,15 @@ struct sii8620_mt_msg;
 typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
 				  struct sii8620_mt_msg *msg);
 
+typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
+
 struct sii8620_mt_msg {
 	struct list_head node;
 	u8 reg[4];
 	u8 ret;
 	sii8620_mt_msg_cb send;
 	sii8620_mt_msg_cb recv;
+	sii8620_cb continuation;
 };
 
 static const u8 sii8620_i2c_page[] = {
@@ -258,6 +261,8 @@ static void sii8620_mt_work(struct sii8620 *ctx)
 				       node);
 		if (msg->recv)
 			msg->recv(ctx, msg);
+		if (msg->continuation)
+			msg->continuation(ctx, msg->ret);
 		list_del(&msg->node);
 		kfree(msg);
 	}
@@ -310,6 +315,21 @@ static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx)
 	return msg;
 }
 
+static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont)
+{
+	struct sii8620_mt_msg *msg;
+
+	if (ctx->error)
+		return;
+
+	if (list_empty(&ctx->mt_queue)) {
+		ctx->error = -EINVAL;
+		return;
+	}
+	msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node);
+	msg->continuation = cont;
+}
+
 static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2)
 {
 	struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);
-- 
2.7.4

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

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

* [PATCH v2 07/25] drm/bridge/sii8620: add support for burst eMSC transmissions
       [not found]         ` <CGME20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc@eucas1p2.samsung.com>
@ 2017-01-26 13:48           ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-26 13:48 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

Burst transmissions are used in MHL3 mode negotiation.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 194 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/bridge/sil-sii8620.h |   4 +
 2 files changed, 197 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 0d3716f..744e685 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -9,6 +9,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <asm/unaligned.h>
+
 #include <drm/bridge/mhl.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
@@ -28,7 +30,8 @@
 
 #include "sil-sii8620.h"
 
-#define VAL_RX_HDMI_CTRL2_DEFVAL	VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
+#define SII8620_BURST_BUF_LEN 288
+#define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
 
 enum sii8620_mode {
 	CM_DISCONNECTED,
@@ -71,6 +74,15 @@ struct sii8620 {
 	unsigned int gen2_write_burst:1;
 	enum sii8620_mt_state mt_state;
 	struct list_head mt_queue;
+	struct {
+		int r_size;
+		int r_count;
+		int rx_ack;
+		int rx_count;
+		u8 rx_buf[32];
+		int tx_count;
+		u8 tx_buf[32];
+	} burst;
 };
 
 struct sii8620_mt_msg;
@@ -511,6 +523,134 @@ static inline void sii8620_mt_read_xdevcap_reg(struct sii8620 *ctx, u8 reg)
 	sii8620_mt_read_devcap_reg(ctx, reg | 0x80);
 }
 
+static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)
+{
+	u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];
+	int size = len + 2;
+
+	if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
+		dev_err(ctx->dev, "TX-BLK buffer exhausted\n");
+		ctx->error = -EINVAL;
+		return NULL;
+	}
+
+	ctx->burst.tx_count += size;
+	buf[1] = len;
+
+	return buf + 2;
+}
+
+static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)
+{
+	u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];
+	int size = len + 1;
+
+	if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
+		dev_err(ctx->dev, "RX-BLK buffer exhausted\n");
+		ctx->error = -EINVAL;
+		return NULL;
+	}
+
+	ctx->burst.rx_count += size;
+	buf[0] = len;
+
+	return buf + 1;
+}
+
+static void sii8620_burst_send(struct sii8620 *ctx)
+{
+	int tx_left = ctx->burst.tx_count;
+	u8 *d = ctx->burst.tx_buf;
+
+	while (tx_left > 0) {
+		int len = d[1] + 2;
+
+		if (ctx->burst.r_count + len > ctx->burst.r_size)
+			break;
+		d[0] = min(ctx->burst.rx_ack, 255);
+		ctx->burst.rx_ack -= d[0];
+		sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, d, len);
+		ctx->burst.r_count += len;
+		tx_left -= len;
+		d += len;
+	}
+
+	ctx->burst.tx_count = tx_left;
+
+	while (ctx->burst.rx_ack > 0) {
+		u8 b[2] = { min(ctx->burst.rx_ack, 255), 0 };
+
+		if (ctx->burst.r_count + 2 > ctx->burst.r_size)
+			break;
+		ctx->burst.rx_ack -= b[0];
+		sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, b, 2);
+		ctx->burst.r_count += 2;
+	}
+}
+
+static void sii8620_burst_receive(struct sii8620 *ctx)
+{
+	u8 buf[3], *d;
+	int count;
+
+	sii8620_read_buf(ctx, REG_EMSCRFIFOBCNTL, buf, 2);
+	count = get_unaligned_le16(buf);
+	while (count > 0) {
+		int len = min(count, 3);
+
+		sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, buf, len);
+		count -= len;
+		ctx->burst.rx_ack += len - 1;
+		ctx->burst.r_count -= buf[1];
+		if (ctx->burst.r_count < 0)
+			ctx->burst.r_count = 0;
+
+		if (len < 3 || !buf[2])
+			continue;
+
+		len = buf[2];
+		d = sii8620_burst_get_rx_buf(ctx, len);
+		if (!d)
+			continue;
+		sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, d, len);
+		count -= len;
+		ctx->burst.rx_ack += len;
+	}
+}
+
+static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
+{
+	struct mhl_burst_blk_rcv_buffer_info *d =
+		sii8620_burst_get_tx_buf(ctx, sizeof(*d));
+	if (!d)
+		return;
+
+	d->id = cpu_to_be16(MHL_BURST_ID_BLK_RCV_BUFFER_INFO);
+	d->size = cpu_to_le16(size);
+}
+
+static void sii8620_burst_rx_all(struct sii8620 *ctx)
+{
+	u8 *d = ctx->burst.rx_buf;
+	int count = ctx->burst.rx_count;
+
+	while (count-- > 0) {
+		int len = *d++;
+		int id = get_unaligned_be16(&d[0]);
+
+		switch (id) {
+		case MHL_BURST_ID_BLK_RCV_BUFFER_INFO:
+			ctx->burst.r_size = get_unaligned_le16(&d[2]);
+			break;
+		default:
+			break;
+		}
+		count -= len;
+		d += len;
+	}
+	ctx->burst.rx_count = 0;
+}
+
 static void sii8620_fetch_edid(struct sii8620 *ctx)
 {
 	u8 lm_ddc, ddc_cmd, int3, cbus;
@@ -1417,6 +1557,19 @@ static void sii8620_irq_coc(struct sii8620 *ctx)
 {
 	u8 stat = sii8620_readb(ctx, REG_COC_INTR);
 
+	if (stat & BIT_COC_CALIBRATION_DONE) {
+		u8 cstat = sii8620_readb(ctx, REG_COC_STAT_0);
+
+		cstat &= BIT_COC_STAT_0_PLL_LOCKED | MSK_COC_STAT_0_FSM_STATE;
+		if (cstat == (BIT_COC_STAT_0_PLL_LOCKED | 0x02)) {
+			sii8620_write_seq_static(ctx,
+				REG_COC_CTLB, 0,
+				REG_TRXINTMH, BIT_TDM_INTR_SYNC_DATA
+					      | BIT_TDM_INTR_SYNC_WAIT
+			);
+		}
+	}
+
 	sii8620_write(ctx, REG_COC_INTR, stat);
 }
 
@@ -1507,6 +1660,41 @@ static void sii8620_irq_infr(struct sii8620 *ctx)
 		sii8620_start_video(ctx);
 }
 
+static void sii8620_irq_tdm(struct sii8620 *ctx)
+{
+	u8 stat = sii8620_readb(ctx, REG_TRXINTH);
+	u8 tdm = sii8620_readb(ctx, REG_TRXSTA2);
+
+	if ((tdm & MSK_TDM_SYNCHRONIZED) == VAL_TDM_SYNCHRONIZED) {
+		ctx->mode = CM_ECBUS_S;
+		ctx->burst.rx_ack = 0;
+		ctx->burst.r_size = SII8620_BURST_BUF_LEN;
+		sii8620_burst_tx_rbuf_info(ctx, SII8620_BURST_BUF_LEN);
+		sii8620_mt_read_devcap(ctx, true);
+	} else {
+		sii8620_write_seq_static(ctx,
+			REG_MHL_PLL_CTL2, 0,
+			REG_MHL_PLL_CTL2, BIT_MHL_PLL_CTL2_CLKDETECT_EN
+		);
+	}
+
+	sii8620_write(ctx, REG_TRXINTH, stat);
+}
+
+static void sii8620_irq_block(struct sii8620 *ctx)
+{
+	u8 stat = sii8620_readb(ctx, REG_EMSCINTR);
+
+	if (stat & BIT_EMSCINTR_SPI_DVLD) {
+		u8 bstat = sii8620_readb(ctx, REG_SPIBURSTSTAT);
+
+		if (bstat & BIT_SPIBURSTSTAT_EMSC_NORMAL_MODE)
+			sii8620_burst_receive(ctx);
+	}
+
+	sii8620_write(ctx, REG_EMSCINTR, stat);
+}
+
 /* endian agnostic, non-volatile version of test_bit */
 static bool sii8620_test_bit(unsigned int nr, const u8 *addr)
 {
@@ -1522,8 +1710,10 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
 		{ BIT_FAST_INTR_STAT_DISC, sii8620_irq_disc },
 		{ BIT_FAST_INTR_STAT_G2WB, sii8620_irq_g2wb },
 		{ BIT_FAST_INTR_STAT_COC, sii8620_irq_coc },
+		{ BIT_FAST_INTR_STAT_TDM, sii8620_irq_tdm },
 		{ BIT_FAST_INTR_STAT_MSC, sii8620_irq_msc },
 		{ BIT_FAST_INTR_STAT_MERR, sii8620_irq_merr },
+		{ BIT_FAST_INTR_STAT_BLOCK, sii8620_irq_block },
 		{ BIT_FAST_INTR_STAT_EDID, sii8620_irq_edid },
 		{ BIT_FAST_INTR_STAT_SCDT, sii8620_irq_scdt },
 		{ BIT_FAST_INTR_STAT_INFR, sii8620_irq_infr },
@@ -1539,7 +1729,9 @@ static irqreturn_t sii8620_irq_thread(int irq, void *data)
 		if (sii8620_test_bit(irq_vec[i].bit, stats))
 			irq_vec[i].handler(ctx);
 
+	sii8620_burst_rx_all(ctx);
 	sii8620_mt_work(ctx);
+	sii8620_burst_send(ctx);
 
 	ret = sii8620_clear_error(ctx);
 	if (ret) {
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index 3ee4e7e..683213a 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -403,12 +403,16 @@
 
 /* TDM RX Status 2nd, default value: 0x00 */
 #define REG_TRXSTA2				0x015c
+#define MSK_TDM_SYNCHRONIZED			0xc0
+#define VAL_TDM_SYNCHRONIZED			0x80
 
 /* TDM RX INT Low, default value: 0x00 */
 #define REG_TRXINTL				0x0163
 
 /* TDM RX INT High, default value: 0x00 */
 #define REG_TRXINTH				0x0164
+#define BIT_TDM_INTR_SYNC_DATA			BIT(0)
+#define BIT_TDM_INTR_SYNC_WAIT			BIT(1)
 
 /* TDM RX INTMASK High, default value: 0x00 */
 #define REG_TRXINTMH				0x0166
-- 
2.7.4

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

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

* [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions
       [not found]             ` <CGME20170126135053eucas1p2b1f31992f4c68a3946aa425f00271e5d@eucas1p2.samsung.com>
@ 2017-01-26 13:50               ` Andrzej Hajda
       [not found]                 ` <CGME20170126135053eucas1p16f3c2d0f36da2616db8fe760c29d0a04@eucas1p1.samsung.com>
  2017-01-31 11:03                 ` [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions Archit Taneja
  0 siblings, 2 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-26 13:50 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL3 protocol uses vendor specific infoframes to transmit additional
information to the sink. This patch adds definitions of structures and
constants used to create such frames.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 include/drm/bridge/mhl.h | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/include/drm/bridge/mhl.h b/include/drm/bridge/mhl.h
index 71d922f..8dfa2cd 100644
--- a/include/drm/bridge/mhl.h
+++ b/include/drm/bridge/mhl.h
@@ -339,4 +339,36 @@ struct mhl_burst_audio_descr {
 	u8 short_desc[9];
 } __packed;
 
+/*
+ * MHL3 infoframe related definitions
+ */
+
+#define MHL3_IEEE_OUI		0x7ca61d
+#define MHL3_INFOFRAME_SIZE	15
+
+enum mhl3_video_format {
+	mhl3_video_format_none,
+	mhl3_video_format_3d,
+	mhl3_video_format_multi_view,
+	mhl3_video_format_dual_3d
+};
+
+enum mhl3_3d_format_type {
+	mhl3_3d_format_type_fs, /* frame sequential */
+	mhl3_3d_format_type_tb, /* top-bottom */
+	mhl3_3d_format_type_lr, /* left-right */
+	mhl3_3d_format_type_fs_tb, /* frame sequential, top-bottom */
+	mhl3_3d_format_type_fs_lr, /* frame sequential, left-right */
+	mhl3_3d_format_type_tb_lr /* top-bottom, left-right */
+};
+
+struct mhl3_infoframe {
+	unsigned char version;
+	enum mhl3_video_format video_format;
+	enum mhl3_3d_format_type format_type;
+	bool sep_audio;
+	int hev_format;
+	int av_delay;
+};
+
 #endif /* __MHL_H__ */
-- 
2.7.4

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

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

* [PATCH v2 19.2/25] drm/bridge/sii8620: rewrite hdmi start sequence
       [not found]                 ` <CGME20170126135053eucas1p16f3c2d0f36da2616db8fe760c29d0a04@eucas1p1.samsung.com>
@ 2017-01-26 13:50                   ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-26 13:50 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

MHL3 protocol requires registry adjustments depending on chosen video mode.
Necessary information is gathered in mode_fixup callback. In case of HDMI
video modes driver should also send special AVI and MHL3 infoframes.
The patch introduces generic helpers for handling MHL3 infoframes, in
case of appearance of other users of MHL3 infoframes these function can
be moved to common library.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/bridge/sil-sii8620.c | 280 +++++++++++++++++++++++++++++++----
 drivers/gpu/drm/bridge/sil-sii8620.h |  15 +-
 2 files changed, 262 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 1c76905..243af5f 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -32,6 +32,8 @@
 
 #define SII8620_BURST_BUF_LEN 288
 #define VAL_RX_HDMI_CTRL2_DEFVAL VAL_RX_HDMI_CTRL2_IDLE_CNT(3)
+#define MHL1_MAX_LCLK 225000
+#define MHL3_MAX_LCLK 600000
 
 enum sii8620_mode {
 	CM_DISCONNECTED,
@@ -62,6 +64,9 @@ struct sii8620 {
 	struct regulator_bulk_data supplies[2];
 	struct mutex lock; /* context lock, protects fields below */
 	int error;
+	int pixel_clock;
+	unsigned int use_packed_pixel:1;
+	int video_code;
 	enum sii8620_mode mode;
 	enum sii8620_sink_type sink_type;
 	u8 cbus_status;
@@ -69,7 +74,7 @@ struct sii8620 {
 	u8 xstat[MHL_XDS_SIZE];
 	u8 devcap[MHL_DCAP_SIZE];
 	u8 xdevcap[MHL_XDC_SIZE];
-	u8 avif[19];
+	u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
 	struct edid *edid;
 	unsigned int gen2_write_burst:1;
 	enum sii8620_mt_state mt_state;
@@ -685,6 +690,40 @@ static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size)
 	d->size = cpu_to_le16(size);
 }
 
+static u8 sii8620_checksum(void *ptr, int size)
+{
+	u8 *d = ptr, sum = 0;
+
+	while (size--)
+		sum += *d++;
+
+	return sum;
+}
+
+static void sii8620_mhl_burst_hdr_set(struct mhl3_burst_header *h,
+	enum mhl_burst_id id)
+{
+	h->id = cpu_to_be16(id);
+	h->total_entries = 1;
+	h->sequence_index = 1;
+}
+
+static void sii8620_burst_tx_bits_per_pixel_fmt(struct sii8620 *ctx, u8 fmt)
+{
+	struct mhl_burst_bits_per_pixel_fmt *d;
+	const int size = sizeof(*d) + sizeof(d->desc[0]);
+
+	d = sii8620_burst_get_tx_buf(ctx, size);
+	if (!d)
+		return;
+
+	sii8620_mhl_burst_hdr_set(&d->hdr, MHL_BURST_ID_BITS_PER_PIXEL_FMT);
+	d->num_entries = 1;
+	d->desc[0].stream_id = 0;
+	d->desc[0].pixel_format = fmt;
+	d->hdr.checksum -= sii8620_checksum(d, size);
+}
+
 static void sii8620_burst_rx_all(struct sii8620 *ctx)
 {
 	u8 *d = ctx->burst.rx_buf;
@@ -949,32 +988,193 @@ static void sii8620_stop_video(struct sii8620 *ctx)
 	sii8620_write(ctx, REG_TPI_SC, val);
 }
 
+static void sii8620_set_format(struct sii8620 *ctx)
+{
+	u8 out_fmt;
+
+	if (sii8620_is_mhl3(ctx)) {
+		sii8620_setbits(ctx, REG_M3_P0CTRL,
+				BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
+				ctx->use_packed_pixel ? ~0 : 0);
+	} else {
+		if (ctx->use_packed_pixel)
+			sii8620_write_seq_static(ctx,
+				REG_VID_MODE, BIT_VID_MODE_M1080P,
+				REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1,
+				REG_MHLTX_CTL6, 0x60
+			);
+		else
+			sii8620_write_seq_static(ctx,
+				REG_VID_MODE, 0,
+				REG_MHL_TOP_CTL, 1,
+				REG_MHLTX_CTL6, 0xa0
+			);
+	}
+
+	if (ctx->use_packed_pixel)
+		out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL) |
+			BIT_TPI_OUTPUT_CSCMODE709;
+	else
+		out_fmt = VAL_TPI_FORMAT(RGB, FULL);
+
+	sii8620_write_seq(ctx,
+		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
+		REG_TPI_OUTPUT, out_fmt,
+	);
+}
+
+static int mhl3_infoframe_init(struct mhl3_infoframe *frame)
+{
+	memset(frame, 0, sizeof(*frame));
+
+	frame->version = 3;
+	frame->hev_format = -1;
+	return 0;
+}
+
+static ssize_t mhl3_infoframe_pack(struct mhl3_infoframe *frame,
+		 void *buffer, size_t size)
+{
+	const int frm_len = HDMI_INFOFRAME_HEADER_SIZE + MHL3_INFOFRAME_SIZE;
+	u8 *ptr = buffer;
+
+	if (size < frm_len)
+		return -ENOSPC;
+
+	memset(buffer, 0, size);
+	ptr[0] = HDMI_INFOFRAME_TYPE_VENDOR;
+	ptr[1] = frame->version;
+	ptr[2] = MHL3_INFOFRAME_SIZE;
+	ptr[4] = MHL3_IEEE_OUI & 0xff;
+	ptr[5] = (MHL3_IEEE_OUI >> 8) & 0xff;
+	ptr[6] = (MHL3_IEEE_OUI >> 16) & 0xff;
+	ptr[7] = frame->video_format & 0x3;
+	ptr[7] |= (frame->format_type & 0x7) << 2;
+	ptr[7] |= frame->sep_audio ? BIT(5) : 0;
+	if (frame->hev_format >= 0) {
+		ptr[9] = 1;
+		ptr[10] = (frame->hev_format >> 8) & 0xff;
+		ptr[11] = frame->hev_format & 0xff;
+	}
+	if (frame->av_delay) {
+		bool sign = frame->av_delay < 0;
+		int delay = sign ? -frame->av_delay : frame->av_delay;
+
+		ptr[12] = (delay >> 16) & 0xf;
+		if (sign)
+			ptr[12] |= BIT(4);
+		ptr[13] = (delay >> 8) & 0xff;
+		ptr[14] = delay & 0xff;
+	}
+	ptr[3] -= sii8620_checksum(buffer, frm_len);
+	return frm_len;
+}
+
+static void sii8620_set_infoframes(struct sii8620 *ctx)
+{
+	struct mhl3_infoframe mhl_frm;
+	union hdmi_infoframe frm;
+	u8 buf[31];
+	int ret;
+
+	if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) {
+		sii8620_write(ctx, REG_TPI_SC,
+			BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
+		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif + 3,
+			ARRAY_SIZE(ctx->avif) - 3);
+		sii8620_write(ctx, REG_PKT_FILTER_0,
+			BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
+			BIT_PKT_FILTER_0_DROP_MPEG_PKT |
+			BIT_PKT_FILTER_0_DROP_GCP_PKT,
+			BIT_PKT_FILTER_1_DROP_GEN_PKT);
+		return;
+	}
+
+	ret = hdmi_avi_infoframe_init(&frm.avi);
+	frm.avi.colorspace = HDMI_COLORSPACE_YUV422;
+	frm.avi.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
+	frm.avi.picture_aspect = HDMI_PICTURE_ASPECT_16_9;
+	frm.avi.colorimetry = HDMI_COLORIMETRY_ITU_709;
+	frm.avi.video_code = ctx->video_code;
+	if (!ret)
+		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, ARRAY_SIZE(buf));
+	if (ret > 0)
+		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3);
+	sii8620_write(ctx, REG_PKT_FILTER_0,
+		BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
+		BIT_PKT_FILTER_0_DROP_MPEG_PKT |
+		BIT_PKT_FILTER_0_DROP_AVI_PKT |
+		BIT_PKT_FILTER_0_DROP_GCP_PKT,
+		BIT_PKT_FILTER_1_VSI_OVERRIDE_DIS |
+		BIT_PKT_FILTER_1_DROP_GEN_PKT |
+		BIT_PKT_FILTER_1_DROP_VSIF_PKT);
+
+	sii8620_write(ctx, REG_TPI_INFO_FSEL, BIT_TPI_INFO_FSEL_EN
+		| BIT_TPI_INFO_FSEL_RPT | VAL_TPI_INFO_FSEL_VSI);
+	ret = mhl3_infoframe_init(&mhl_frm);
+	if (!ret)
+		ret = mhl3_infoframe_pack(&mhl_frm, buf, ARRAY_SIZE(buf));
+	sii8620_write_buf(ctx, REG_TPI_INFO_B0, buf, ret);
+}
+
 static void sii8620_start_hdmi(struct sii8620 *ctx)
 {
 	sii8620_write_seq_static(ctx,
 		REG_RX_HDMI_CTRL2, VAL_RX_HDMI_CTRL2_DEFVAL
 			| BIT_RX_HDMI_CTRL2_USE_AV_MUTE,
 		REG_VID_OVRRD, BIT_VID_OVRRD_PP_AUTO_DISABLE
-			| BIT_VID_OVRRD_M1080P_OVRRD,
-		REG_VID_MODE, 0,
-		REG_MHL_TOP_CTL, 0x1,
-		REG_MHLTX_CTL6, 0xa0,
-		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
-		REG_TPI_OUTPUT, VAL_TPI_FORMAT(RGB, FULL),
-	);
-
-	sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
-			      MHL_DST_LM_CLK_MODE_NORMAL |
-			      MHL_DST_LM_PATH_ENABLED);
+			| BIT_VID_OVRRD_M1080P_OVRRD);
+	sii8620_set_format(ctx);
 
-	sii8620_set_auto_zone(ctx);
+	if (!sii8620_is_mhl3(ctx)) {
+		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
+			MHL_DST_LM_CLK_MODE_NORMAL | MHL_DST_LM_PATH_ENABLED);
+		sii8620_set_auto_zone(ctx);
+	} else {
+		static const struct {
+			int max_clk;
+			u8 zone;
+			u8 link_rate;
+			u8 rrp_decode;
+		} clk_spec[] = {
+			{ 150000, VAL_TX_ZONE_CTL3_TX_ZONE_1_5GBPS,
+			  MHL_XDS_LINK_RATE_1_5_GBPS, 0x38 },
+			{ 300000, VAL_TX_ZONE_CTL3_TX_ZONE_3GBPS,
+			  MHL_XDS_LINK_RATE_3_0_GBPS, 0x40 },
+			{ 600000, VAL_TX_ZONE_CTL3_TX_ZONE_6GBPS,
+			  MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 },
+		};
+		u8 p0_ctrl = BIT_M3_P0CTRL_MHL3_P0_PORT_EN;
+		int clk = ctx->pixel_clock * (ctx->use_packed_pixel ? 2 : 3);
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(clk_spec); ++i)
+			if (clk < clk_spec[i].max_clk)
+				break;
 
-	sii8620_write(ctx, REG_TPI_SC, BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
+		if (100 * clk >= 98 * clk_spec[i].max_clk)
+			p0_ctrl |= BIT_M3_P0CTRL_MHL3_P0_UNLIMIT_EN;
 
-	sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif,
-			  ARRAY_SIZE(ctx->avif));
+		sii8620_burst_tx_bits_per_pixel_fmt(ctx, ctx->use_packed_pixel);
+		sii8620_burst_send(ctx);
+		sii8620_write_seq(ctx,
+			REG_MHL_DP_CTL0, 0xf0,
+			REG_MHL3_TX_ZONE_CTL, clk_spec[i].zone);
+		sii8620_setbits(ctx, REG_M3_P0CTRL,
+			BIT_M3_P0CTRL_MHL3_P0_PORT_EN
+			| BIT_M3_P0CTRL_MHL3_P0_UNLIMIT_EN, p0_ctrl);
+		sii8620_setbits(ctx, REG_M3_POSTM, MSK_M3_POSTM_RRP_DECODE,
+			clk_spec[i].rrp_decode);
+		sii8620_write_seq_static(ctx,
+			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE
+				| BIT_M3_CTRL_H2M_SWRST,
+			REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE
+		);
+		sii8620_mt_write_stat(ctx, MHL_XDS_REG(AVLINK_MODE_CONTROL),
+			clk_spec[i].link_rate);
+	}
 
-	sii8620_write(ctx, REG_PKT_FILTER_0, 0xa1, 0x2);
+	sii8620_set_infoframes(ctx);
 }
 
 static void sii8620_start_video(struct sii8620 *ctx)
@@ -1834,22 +2034,44 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge,
 			       struct drm_display_mode *adjusted_mode)
 {
 	struct sii8620 *ctx = bridge_to_sii8620(bridge);
-	bool ret = false;
-	int max_clock = 74250;
-
-	mutex_lock(&ctx->lock);
-
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		goto out;
+	int max_lclk;
+	bool ret = true;
 
-	if (ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL)
-		max_clock = 300000;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return false;
 
-	ret = mode->clock <= max_clock;
+	mutex_lock(&ctx->lock);
 
-out:
+	max_lclk = sii8620_is_mhl3(ctx) ? MHL3_MAX_LCLK : MHL1_MAX_LCLK;
+	if (max_lclk > 3 * adjusted_mode->clock) {
+		ctx->use_packed_pixel = 0;
+		goto end;
+	}
+	if ((ctx->devcap[MHL_DCAP_VID_LINK_MODE] & MHL_DCAP_VID_LINK_PPIXEL) &&
+	    max_lclk > 2 * adjusted_mode->clock) {
+		ctx->use_packed_pixel = 1;
+		goto end;
+	}
+	ret = false;
+end:
+	if (ret) {
+		u8 vic = drm_match_cea_mode(adjusted_mode);
+
+		if (!vic) {
+			union hdmi_infoframe frm;
+			u8 mhl_vic[] = { 0, 95, 94, 93, 98 };
+
+			drm_hdmi_vendor_infoframe_from_display_mode(
+				&frm.vendor.hdmi, adjusted_mode);
+			vic = frm.vendor.hdmi.vic;
+			if (vic >= ARRAY_SIZE(mhl_vic))
+				vic = 0;
+			vic = mhl_vic[vic];
+		}
+		ctx->video_code = vic;
+		ctx->pixel_clock = adjusted_mode->clock;
+	}
 	mutex_unlock(&ctx->lock);
-
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.h b/drivers/gpu/drm/bridge/sil-sii8620.h
index 683213a..613943a 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.h
+++ b/drivers/gpu/drm/bridge/sil-sii8620.h
@@ -1084,10 +1084,17 @@
 
 /* TPI Info Frame Select, default value: 0x00 */
 #define REG_TPI_INFO_FSEL			0x06bf
-#define BIT_TPI_INFO_FSEL_TPI_INFO_EN		BIT(7)
-#define BIT_TPI_INFO_FSEL_TPI_INFO_RPT		BIT(6)
-#define BIT_TPI_INFO_FSEL_TPI_INFO_READ_FLAG	BIT(5)
-#define MSK_TPI_INFO_FSEL_TPI_INFO_SEL		0x07
+#define BIT_TPI_INFO_FSEL_EN			BIT(7)
+#define BIT_TPI_INFO_FSEL_RPT			BIT(6)
+#define BIT_TPI_INFO_FSEL_READ_FLAG		BIT(5)
+#define MSK_TPI_INFO_FSEL_PKT			0x07
+#define VAL_TPI_INFO_FSEL_AVI			0x00
+#define VAL_TPI_INFO_FSEL_SPD			0x01
+#define VAL_TPI_INFO_FSEL_AUD			0x02
+#define VAL_TPI_INFO_FSEL_MPG			0x03
+#define VAL_TPI_INFO_FSEL_GEN			0x04
+#define VAL_TPI_INFO_FSEL_GEN2			0x05
+#define VAL_TPI_INFO_FSEL_VSI			0x06
 
 /* TPI Info Byte #0, default value: 0x00 */
 #define REG_TPI_INFO_B0				0x06c0
-- 
2.7.4

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

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

* Re: [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions
  2017-01-26 13:50               ` [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions Andrzej Hajda
       [not found]                 ` <CGME20170126135053eucas1p16f3c2d0f36da2616db8fe760c29d0a04@eucas1p1.samsung.com>
@ 2017-01-31 11:03                 ` Archit Taneja
  2017-01-31 12:41                   ` Andrzej Hajda
  1 sibling, 1 reply; 42+ messages in thread
From: Archit Taneja @ 2017-01-31 11:03 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz



On 01/26/2017 07:20 PM, Andrzej Hajda wrote:
> MHL3 protocol uses vendor specific infoframes to transmit additional
> information to the sink. This patch adds definitions of structures and
> constants used to create such frames.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  include/drm/bridge/mhl.h | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
>
> diff --git a/include/drm/bridge/mhl.h b/include/drm/bridge/mhl.h
> index 71d922f..8dfa2cd 100644
> --- a/include/drm/bridge/mhl.h
> +++ b/include/drm/bridge/mhl.h
> @@ -339,4 +339,36 @@ struct mhl_burst_audio_descr {
>  	u8 short_desc[9];
>  } __packed;
>
> +/*
> + * MHL3 infoframe related definitions
> + */
> +
> +#define MHL3_IEEE_OUI		0x7ca61d
> +#define MHL3_INFOFRAME_SIZE	15
> +
> +enum mhl3_video_format {
> +	mhl3_video_format_none,
> +	mhl3_video_format_3d,
> +	mhl3_video_format_multi_view,
> +	mhl3_video_format_dual_3d
> +};
> +
> +enum mhl3_3d_format_type {
> +	mhl3_3d_format_type_fs, /* frame sequential */
> +	mhl3_3d_format_type_tb, /* top-bottom */
> +	mhl3_3d_format_type_lr, /* left-right */
> +	mhl3_3d_format_type_fs_tb, /* frame sequential, top-bottom */
> +	mhl3_3d_format_type_fs_lr, /* frame sequential, left-right */
> +	mhl3_3d_format_type_tb_lr /* top-bottom, left-right */
> +};
> +

Can we keep the enums in caps?

Thanks,
Archit

> +struct mhl3_infoframe {
> +	unsigned char version;
> +	enum mhl3_video_format video_format;
> +	enum mhl3_3d_format_type format_type;
> +	bool sep_audio;
> +	int hev_format;
> +	int av_delay;
> +};
> +
>  #endif /* __MHL_H__ */
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions
  2017-01-31 11:03                 ` [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions Archit Taneja
@ 2017-01-31 12:41                   ` Andrzej Hajda
  0 siblings, 0 replies; 42+ messages in thread
From: Andrzej Hajda @ 2017-01-31 12:41 UTC (permalink / raw)
  To: Archit Taneja, dri-devel; +Cc: Marek Szyprowski, Bartlomiej Zolnierkiewicz

On 31.01.2017 12:03, Archit Taneja wrote:
>
> On 01/26/2017 07:20 PM, Andrzej Hajda wrote:
>> MHL3 protocol uses vendor specific infoframes to transmit additional
>> information to the sink. This patch adds definitions of structures and
>> constants used to create such frames.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> ---
>>  include/drm/bridge/mhl.h | 32 ++++++++++++++++++++++++++++++++
>>  1 file changed, 32 insertions(+)
>>
>> diff --git a/include/drm/bridge/mhl.h b/include/drm/bridge/mhl.h
>> index 71d922f..8dfa2cd 100644
>> --- a/include/drm/bridge/mhl.h
>> +++ b/include/drm/bridge/mhl.h
>> @@ -339,4 +339,36 @@ struct mhl_burst_audio_descr {
>>  	u8 short_desc[9];
>>  } __packed;
>>
>> +/*
>> + * MHL3 infoframe related definitions
>> + */
>> +
>> +#define MHL3_IEEE_OUI		0x7ca61d
>> +#define MHL3_INFOFRAME_SIZE	15
>> +
>> +enum mhl3_video_format {
>> +	mhl3_video_format_none,
>> +	mhl3_video_format_3d,
>> +	mhl3_video_format_multi_view,
>> +	mhl3_video_format_dual_3d
>> +};
>> +
>> +enum mhl3_3d_format_type {
>> +	mhl3_3d_format_type_fs, /* frame sequential */
>> +	mhl3_3d_format_type_tb, /* top-bottom */
>> +	mhl3_3d_format_type_lr, /* left-right */
>> +	mhl3_3d_format_type_fs_tb, /* frame sequential, top-bottom */
>> +	mhl3_3d_format_type_fs_lr, /* frame sequential, left-right */
>> +	mhl3_3d_format_type_tb_lr /* top-bottom, left-right */
>> +};
>> +
> Can we keep the enums in caps?

Ups, will fix it now :)

Regards
Andrzej

>
> Thanks,
> Archit
>
>> +struct mhl3_infoframe {
>> +	unsigned char version;
>> +	enum mhl3_video_format video_format;
>> +	enum mhl3_3d_format_type format_type;
>> +	bool sep_audio;
>> +	int hev_format;
>> +	int av_delay;
>> +};
>> +
>>  #endif /* __MHL_H__ */
>>

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

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

end of thread, other threads:[~2017-01-31 12:41 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20170120073854eucas1p1f401f4de15eae3c0dc56aa47bef0a445@eucas1p1.samsung.com>
2017-01-20  7:38 ` [PATCH 00/24] drm/bridge/sii8620: add Ultra HD modes support Andrzej Hajda
     [not found]   ` <CGME20170120073854eucas1p18dacd6261e9453a83c205bb0da7ecdd0@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 01/24] drm/bridge/sii8620: simplify MHL3 mode setting Andrzej Hajda
     [not found]   ` <CGME20170120073855eucas1p18346c334bc74766a8af9ba76f3e8beb9@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 02/24] drm/bridge/sii8620: add MHL3 mode check helper Andrzej Hajda
     [not found]   ` <CGME20170120073855eucas1p1b8c6196a51ba9608cee9112dfa3c8f2c@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 03/24] drm/bridge/sii8620: add reading device capability registers Andrzej Hajda
     [not found]   ` <CGME20170120073855eucas1p1568d429ab0bfc41451183cca9f1c183a@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 04/24] drm/bridge/sii8620: add continuations to messages Andrzej Hajda
2017-01-23  8:31       ` Archit Taneja
2017-01-23 10:33         ` Andrzej Hajda
2017-01-24  7:57           ` Archit Taneja
     [not found]         ` <CGME20170126134315eucas1p1db71a5e2f14fd93283d14a2da4f05611@eucas1p1.samsung.com>
2017-01-26 13:43           ` [PATCH v2 04/25] " Andrzej Hajda
     [not found]   ` <CGME20170120073856eucas1p1fa2a6007c5073f08c62f2c98aadb1726@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 05/24] drm/bridge/sii8620: initial support for eCBUS-S mode Andrzej Hajda
     [not found]   ` <CGME20170120073856eucas1p1124fd039bd23e0add19dced61a55852a@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 06/24] drm/bridge/mhl: add write burst related definitions Andrzej Hajda
     [not found]   ` <CGME20170120073857eucas1p2669acdcb12a64294bccebece4990fb5c@eucas1p2.samsung.com>
2017-01-20  7:38     ` [PATCH 07/24] drm/bridge/sii8620: add support for burst eMSC transmissions Andrzej Hajda
2017-01-23  8:20       ` Archit Taneja
2017-01-23 10:38         ` Andrzej Hajda
     [not found]         ` <CGME20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc@eucas1p2.samsung.com>
2017-01-26 13:48           ` [PATCH v2 07/25] " Andrzej Hajda
     [not found]   ` <CGME20170120073857eucas1p14c07f158f99c6d89d7d879c28afbeafc@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 08/24] drm/bridge/sii8620: respond to feature requests Andrzej Hajda
     [not found]   ` <CGME20170120073857eucas1p1776cb0ca12d233450c81cbeab053f729@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 09/24] drm/bridge/sii8620: fix peer device capabilities read code Andrzej Hajda
     [not found]   ` <CGME20170120073857eucas1p18fa1efe180224d8bba37ec598d09b9ac@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 10/24] drm/bridge/sii8620: remove spare CBUS bring-up sequence Andrzej Hajda
     [not found]   ` <CGME20170120073858eucas1p1f833db10ddca4a46be42f7b879063fd1@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 11/24] drm/bridge/sii8620: fix MSC message removal Andrzej Hajda
     [not found]   ` <CGME20170120073858eucas1p15c1f5ddb032763d29ad045d1416a4f10@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 12/24] drm/bridge/sii8620: fix initialization sequence for MHL2 receivers Andrzej Hajda
     [not found]   ` <CGME20170120073859eucas1p2c241656291e20876c3e36133ab8f145e@eucas1p2.samsung.com>
2017-01-20  7:38     ` [PATCH 13/24] drm/bridge/sii8620: abstract out sink detection code Andrzej Hajda
     [not found]   ` <CGME20170120073859eucas1p11cc6d9d02494c47b0e3a671378552064@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 14/24] drm/bridge/sii8620: set gen2 write burst before sending MSC command Andrzej Hajda
     [not found]   ` <CGME20170120073859eucas1p1605dfb90b8357a12339b9a6661ec7d7d@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 15/24] drm/bridge/sii8620: do not stop MHL output when TMDS input is stopped Andrzej Hajda
     [not found]   ` <CGME20170120073900eucas1p23f98ec5ce9d624e85611a77f60d65402@eucas1p2.samsung.com>
2017-01-20  7:38     ` [PATCH 16/24] drm/bridge/sii8620: add delay during cbus reset Andrzej Hajda
     [not found]   ` <CGME20170120073900eucas1p15da0726bf6e9bcdf0d9a7bbfea670918@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 17/24] drm/bridge/sii8620: split EDID read and write code Andrzej Hajda
2017-01-24 10:31       ` Archit Taneja
2017-01-24 11:39         ` Andrzej Hajda
2017-01-25  9:48           ` Archit Taneja
     [not found]   ` <CGME20170120073900eucas1p158ae6deea9833bac7f8a2f1199878f15@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 18/24] drm/bridge/sii8620: fix disconnect sequence Andrzej Hajda
     [not found]   ` <CGME20170120073900eucas1p1b08b14e7cee9378d3b61016370a0ebef@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 19/24] drm/bridge/sii8620: rewrite hdmi start sequence Andrzej Hajda
2017-01-23  9:17       ` Archit Taneja
2017-01-23 11:12         ` Andrzej Hajda
2017-01-24  8:09           ` Archit Taneja
     [not found]             ` <CGME20170126135053eucas1p2b1f31992f4c68a3946aa425f00271e5d@eucas1p2.samsung.com>
2017-01-26 13:50               ` [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions Andrzej Hajda
     [not found]                 ` <CGME20170126135053eucas1p16f3c2d0f36da2616db8fe760c29d0a04@eucas1p1.samsung.com>
2017-01-26 13:50                   ` [PATCH v2 19.2/25] drm/bridge/sii8620: rewrite hdmi start sequence Andrzej Hajda
2017-01-31 11:03                 ` [PATCH v2 19.1/25] drm/bridge/mhl: add MHL3 infoframe related definitions Archit Taneja
2017-01-31 12:41                   ` Andrzej Hajda
     [not found]   ` <CGME20170120073901eucas1p134403a09cc3ac008c9a3285b31aef888@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 20/24] drm/bridge/sii8620: send EMSC features on request Andrzej Hajda
     [not found]   ` <CGME20170120073901eucas1p1c4c9ca4b72fc1e418775f59e6c3579f2@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 21/24] drm/bridge/sii8620: improve gen2 write burst IRQ routine Andrzej Hajda
     [not found]   ` <CGME20170120073901eucas1p1f254c73eb4c49024b575f4ab02d56b65@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 22/24] drm/bridge/sii8620: add HSIC initialization code Andrzej Hajda
     [not found]   ` <CGME20170120073902eucas1p27c5b9a57fa5461e227ad090b17af0e8c@eucas1p2.samsung.com>
2017-01-20  7:38     ` [PATCH 23/24] drm/bridge/sii8620: enable MHL3 mode if possible Andrzej Hajda
     [not found]   ` <CGME20170120073902eucas1p145a70cf76319defe839cf5be0bba3870@eucas1p1.samsung.com>
2017-01-20  7:38     ` [PATCH 24/24] drm/bridge/sii8620: enable interlace modes Andrzej Hajda

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