From patchwork Thu Jan 26 13:48:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9539285 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 18FE460429 for ; Thu, 26 Jan 2017 13:49:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 01BA627F17 for ; Thu, 26 Jan 2017 13:49:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E8094280F4; Thu, 26 Jan 2017 13:49:03 +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 D4BEB27F17 for ; Thu, 26 Jan 2017 13:49:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2E2E66EBA2; Thu, 26 Jan 2017 13:49:02 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout3.w1.samsung.com (mailout3.w1.samsung.com [210.118.77.13]) by gabe.freedesktop.org (Postfix) with ESMTPS id BD2EE6EBA2 for ; Thu, 26 Jan 2017 13:49:00 +0000 (UTC) Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OKE00M9Z3PLBO40@mailout3.w1.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 26 Jan 2017 13:48:57 +0000 (GMT) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170126134857eucas1p1967933f32bb0fc2b4a9699f8cfc6a4b2~dVnrCKPy51590715907eucas1p1M; Thu, 26 Jan 2017 13:48:57 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges5.samsung.com (EUCPMTA) with SMTP id 8C.39.17477.94EF9885; Thu, 26 Jan 2017 13:48:57 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc~dVnqGlLGL3078730787eucas1p2K; Thu, 26 Jan 2017 13:48:56 +0000 (GMT) X-AuditID: cbfec7f5-f79d06d000004445-f3-5889fe49636c Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 86.12.10233.54EF9885; Thu, 26 Jan 2017 13:48:53 +0000 (GMT) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OKE00AHG3PJS080@eusync3.samsung.com>; Thu, 26 Jan 2017 13:48:55 +0000 (GMT) From: Andrzej Hajda To: Archit Taneja , dri-devel@lists.freedesktop.org Subject: [PATCH v2 07/25] drm/bridge/sii8620: add support for burst eMSC transmissions Date: Thu, 26 Jan 2017 14:48:43 +0100 Message-id: <1485438523-12315-1-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <004743c4-0483-4291-8931-b7508db1e0d6@codeaurora.org> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrNIsWRmVeSWpSXmKPExsWy7djP87qe/zojDL48ZLW4te4cq0VTx1tW i40z1rNaXPn6ns1i0v0JLBZrj9xld2DzuNzXy+Rxv/s4k0ffllWMAcxRXDYpqTmZZalF+nYJ XBln1rxhK3hsW7Hn+gW2BsaJRl2MnBwSAiYS32feY4GwxSQu3FvP1sXIxSEksJRR4sn9FmYI 5zOjxIu7VxlhOuYfOsgIkVjGKDFvzXwmCOc/o8Te7w/AZrEJaEr83XyTDcQWEfCWmLO6D6yb WWA9o8S1U3EgtrBAhMSWe1/A6lkEVCVWndnICmLzCjhLvF11AGqbnMTNc53MIDangJPE/yOf wTZLCNxnk1i4fwtQAweQIyux6QAzhOki8XefAkSrsMSr41vYIWwZicuTu1kgWrsZJT71n2CH cKYwSvz7MIMZospa4vDxi6wQh/JJTNo2HWoor0RHmxCE6SHR+EELotpRomXBfVaI36cySlw+ cpNlAqPMAkaGVYwiqaXFuempxaZ6xYm5xaV56XrJ+bmbGIFRevrf8a87GJceszrEKMDBqMTD e2BHR4QQa2JZcWXuIUYJDmYlEd7PvzsjhHhTEiurUovy44tKc1KLDzFKc7AoifPuWXAlXEgg PbEkNTs1tSC1CCbLxMEp1cDILif5r01jlWnb64qz+d92zDje8EfWY2ZVWPpby6XhvleCmg8x tb2UnXy+4bL1purM/nyW+WXO+7z+Ge6xz5nEdsWWI4wxuEezblLGbIXO103lXGe7Zl07275a v4iv68zkLfE5UyIvK6Qn/Xx7fYZoscXJ561uyjsTlydc+rfC43PyknNBe78psRRnJBpqMRcV JwIAU1/RG84CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNLMWRmVeSWpSXmKPExsVy+t/xq7qu/zojDB7eULG4te4cq0VTx1tW i40z1rNaXPn6ns1i0v0JLBZrj9xld2DzuNzXy+Rxv/s4k0ffllWMAcxRbjYZqYkpqUUKqXnJ +SmZeem2SqEhbroWSgp5ibmptkoRur4hQUoKZYk5pUCekQEacHAOcA9W0rdLcMs4s+YNW8Fj 24o91y+wNTBONOpi5OSQEDCRmH/oICOELSZx4d56NhBbSGAJo8T047FdjFxAdiOTxIqHX1lB EmwCmhJ/N98EKxIR8JaYs7qPEaSIWWA9o8TUx3/ZQRLCAhESW+59YQGxWQRUJVad2QjWzCvg LPF21QGobXISN891MoPYnAJOEv+PfGaE2OwosajtE9MERt4FjAyrGEVSS4tz03OLjfSKE3OL S/PS9ZLzczcxAgN227GfW3Ywdr0LPsQowMGoxMObsa0jQog1say4MvcQowQHs5II7+ffnRFC vCmJlVWpRfnxRaU5qcWHGE2BjprILCWanA+MprySeEMTQ3NLQyNjCwtzIyMlcd6pH66ECwmk J5akZqemFqQWwfQxcXBKNTAKPUwRLb3V3X1Ys/JNbU9dRv6BpI8Z+wqvcZ9Y91dP4q/33bgT vgtFeH4F8DIGBCfE9tx2eKRV17bqiWmi0zS7otKVZqt1779et0D+36w0hlff4+Zo80412vtc oo7Pl1X384ywXzrJ5hdPbQlqD1v2m9V5LueRMxfdnymJcM8PuLe9sTrh7S4lluKMREMt5qLi RAClD46ObgIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc 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: 20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc X-RootMTR: 20170126134856eucas1p246afc30ebae5b1050f75dac8dc6df9bc References: <004743c4-0483-4291-8931-b7508db1e0d6@codeaurora.org> Cc: Marek Szyprowski , Bartlomiej Zolnierkiewicz 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