From patchwork Wed Feb 1 07:47:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9549009 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5E5E060425 for ; Wed, 1 Feb 2017 07:48:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F47D28338 for ; Wed, 1 Feb 2017 07:48:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4407A28375; Wed, 1 Feb 2017 07:48:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C10A928338 for ; Wed, 1 Feb 2017 07:48:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DB4866E5CB; Wed, 1 Feb 2017 07:47:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) by gabe.freedesktop.org (Postfix) with ESMTPS id E24BC6E57D for ; Wed, 1 Feb 2017 07:47:58 +0000 (UTC) Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OKO00A37QZWI960@mailout2.w1.samsung.com> for dri-devel@lists.freedesktop.org; Wed, 01 Feb 2017 07:47:56 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170201074756eucas1p1e482c984108b3b28643294c0fe073800~fGkLPvZgZ1258412584eucas1p1i; Wed, 1 Feb 2017 07:47:56 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2.samsung.com (EUCPMTA) with SMTP id EE.1D.30614.CA291985; Wed, 1 Feb 2017 07:47:56 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170201074755eucas1p20b504ad5964b6cc81097265bd787ae43~fGkKlejEw1804718047eucas1p2V; Wed, 1 Feb 2017 07:47:55 +0000 (GMT) X-AuditID: cbfec7f1-f793f6d000007796-0c-589192acd76b Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 2E.35.10233.AA291985; Wed, 1 Feb 2017 07:47:54 +0000 (GMT) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OKO00GROQZTN370@eusync1.samsung.com>; Wed, 01 Feb 2017 07:47:55 +0000 (GMT) From: Andrzej Hajda To: Archit Taneja , dri-devel@lists.freedesktop.org Subject: [PATCH v3 07/25] drm/bridge/sii8620: add support for burst eMSC transmissions Date: Wed, 01 Feb 2017 08:47:34 +0100 Message-id: <1485935272-17337-8-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1485935272-17337-1-git-send-email-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprBIsWRmVeSWpSXmKPExsWy7djP87prJk2MMHg3gdmiqeMtq8WVr+/Z HJg8Lvf1Mnnc7z7OFMAUxWWTkpqTWZZapG+XwJVxZs0btoLHthV7rl9ga2CcaNTFyMkhIWAi 8fTePhYIW0ziwr31bF2MXBxCAksZJRasucIC4XxmlNixZBobTMeymfeZIBLLGCW+9a5lhHD+ M0qcPf2SFaSKTUBT4u/mm2AdIgLeEnNW9zGC2MICERI7Jl8Fq2ERUJVY8mYhO4jNK+As8at/ OTPEBjmJm+c6wWxOAReJ5wvngJ0hIbCETeLgtXtADRxAjqzEpgNQ9S4SvWs3Q/0gLPHq+BZ2 CFtG4vLkbqjebkaJT/0n2CGcKYwS/z7MgOq2ljh8/CLYRcwCfBKTtk1nhljAK9HRJgRR4iHx dkovK4TtKHGjbxcrxMfTGSVWH9zAOIFRegEjwypGkdTS4tz01GIjveLE3OLSvHS95PzcTYzA +Dr97/jHHYzvT1gdYhTgYFTi4Z1xckKEEGtiWXFl7iFGCQ5mJRHeGf0TI4R4UxIrq1KL8uOL SnNSiw8xSnOwKInz7llwJVxIID2xJDU7NbUgtQgmy8TBKdXAaKZ3d/vL5Rb9hiXbqtZW5fz8 KBcvezPNbWvDsVXKnC+W5S6f/fKcydca/+lmuWVhxmeOqXz/ViHyQuizwPdXG7M41k78wdEa zHdt4nKZm2XMCX1zgxd8y38YxHFyx6RF5YtfzuzZcnDjVNlj535EPWe/ohaa31vzPHbuh4Od l48c3bdI6YqnX5QSS3FGoqEWc1FxIgA138fbqwIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCLMWRmVeSWpSXmKPExsVy+t/xy7qrJk2MMJiwWNOiqeMtq8WVr+/Z HJg8Lvf1Mnnc7z7OFMAU5WaTkZqYklqkkJqXnJ+SmZduqxQa4qZroaSQl5ibaqsUoesbEqSk UJaYUwrkGRmgAQfnAPdgJX27BLeMM2vesBU8tq3Yc/0CWwPjRKMuRk4OCQETiWUz7zNB2GIS F+6tZwOxhQSWMEq8/ZQHYTcySXycVA9iswloSvzdfBOsRkTAW2LO6j5GEFtYIEJix+SrrCA2 i4CqxJI3C9lBbF4BZ4lf/cuZIebLSdw81wlmcwq4SDxfOIcFYr6zxLe7s9gnMPIsYGRYxSiS Wlqcm55bbKRXnJhbXJqXrpecn7uJERhi24793LKDsetd8CFGAQ5GJR7eD6cnRAixJpYVV+Ye YpTgYFYS4Z3RPzFCiDclsbIqtSg/vqg0J7X4EKMp0FETmaVEk/OB4Z9XEm9oYmhuaWhkbGFh bmSkJM479cOVcCGB9MSS1OzU1ILUIpg+Jg5OqQbGVdJr6nXe1c57KTw1q+Bjd5rytPJJ7xn9 C+7uOHr0yK9pd78+Ov3iLtPG3/5vGvwdN1ws2f7xmKbao1JeluiDFTqH3LUyg640PZmULOBn /O/Fhf3/T6TsOhj59/z11yHGDtVtAtOULGRcQ/7HCcy+bcied+vc9PlsZvcXnMr0Xcp2RYEj q0xotxJLcUaioRZzUXEiAN7INFtHAgAA X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170201074755eucas1p20b504ad5964b6cc81097265bd787ae43 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRvsgrw=?= =?UTF-8?B?7ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRtTYW1z?= =?UTF-8?B?dW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170201074755eucas1p20b504ad5964b6cc81097265bd787ae43 X-RootMTR: 20170201074755eucas1p20b504ad5964b6cc81097265bd787ae43 References: <1485935272-17337-1-git-send-email-a.hajda@samsung.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Burst transmissions are used in MHL3 mode negotiation. Signed-off-by: Andrzej Hajda --- 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 + #include #include #include @@ -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