From patchwork Fri Jan 20 07:38:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9527635 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 322FB60434 for ; Fri, 20 Jan 2017 07:39:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2294B28452 for ; Fri, 20 Jan 2017 07:39:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 178A828620; Fri, 20 Jan 2017 07:39:12 +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 9317B28452 for ; Fri, 20 Jan 2017 07:39:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DE00D6EB30; Fri, 20 Jan 2017 07:39:02 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout1.w1.samsung.com (mailout1.w1.samsung.com [210.118.77.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id 676886EB27 for ; Fri, 20 Jan 2017 07:38:59 +0000 (UTC) Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OK200F6DIKXOD50@mailout1.w1.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 20 Jan 2017 07:38:58 +0000 (GMT) Received: from eusmges3.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170120073857eucas1p2c1ce7fefa41eeb3b70513bc8996c21b0~bas6WGwxt1833418334eucas1p2b; Fri, 20 Jan 2017 07:38:57 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3.samsung.com (EUCPMTA) with SMTP id 20.E2.09557.19EB1885; Fri, 20 Jan 2017 07:38:57 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170120073857eucas1p2669acdcb12a64294bccebece4990fb5c~bas5vr_ch3262732627eucas1p2S; Fri, 20 Jan 2017 07:38:57 +0000 (GMT) X-AuditID: cbfec7f2-f790f6d000002555-47-5881be91d567 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id F5.47.10233.C8EB1885; Fri, 20 Jan 2017 07:38:52 +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 <0OK200LE1IKT7D70@eusync1.samsung.com>; Fri, 20 Jan 2017 07:38:56 +0000 (GMT) From: Andrzej Hajda To: Archit Taneja , dri-devel@lists.freedesktop.org Subject: [PATCH 07/24] drm/bridge/sii8620: add support for burst eMSC transmissions Date: Fri, 20 Jan 2017 08:38:33 +0100 Message-id: <1484897930-1275-8-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1484897930-1275-1-git-send-email-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrDIsWRmVeSWpSXmKPExsWy7djP87oT9zVGGBxcLm5xa905Voumjres FhtnrGe1uPL1PZvFpPsTWCzWHrnL7sDmcbmvl8njfvdxJo++LasYA5ijuGxSUnMyy1KL9O0S uDIWTXnAXtDtUPF21hG2BsZfxl2MnBwSAiYSrc/es0DYYhIX7q1n62Lk4hASWMoo8fzGMUYI 5zOjxNxP59hhOg5t6YFKLGOU+HztBBOE859RYsuif6wgVWwCmhJ/N99kA7FFBLwl5qzuYwSx mQXWM0pcOxUHYgsLhEosnvWNGcRmEVCVuPd0KlgNr4CTxM8t35kgtslJ3DzXCVbDKeAscf7G F7BlEgL32SQW3tgI5HAAObISmw4wQ9S7SBx/1QVlC0u8Or4F6moZicuTu1kgersZJT71n2CH cKYwSvz7MAOqw1ri8PGLrBCX8klM2jadGWIBr0RHmxBEiYfEyWOzofY6SvT0y0A8P41Rov9l P+sERpkFjAyrGEVSS4tz01OLjfWKE3OLS/PS9ZLzczcxAuP09L/jn3Ywfj1hdYhRgINRiYd3 x4mGCCHWxLLiytxDjBIczEoivD3rGyOEeFMSK6tSi/Lji0pzUosPMUpzsCiJ8+5ZcCVcSCA9 sSQ1OzW1ILUIJsvEwSnVwMjVtzTDxen+j4N6zw7MM826USLldWCufqq//XWlgM9f5y5zKfq6 1TzraPrtr9kzv+rvVWeM7lx49fSSWzJ7S85JTBepPPfxrvT5XzwKJ9Yfkdu0bbv1tskHrDNd vd3u7JTpeSOvJRgWpzZhbv/VFddVI5TWbzia4sQaOElk2QlPL7MQiwnejK5KLMUZiYZazEXF iQBhMrjkzwIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrFLMWRmVeSWpSXmKPExsVy+t/xy7o9+xojDLovi1rcWneO1aKp4y2r xcYZ61ktrnx9z2Yx6f4EFou1R+6yO7B5XO7rZfK4332cyaNvyyrGAOYoN5uM1MSU1CKF1Lzk /JTMvHRbpdAQN10LJYW8xNxUW6UIXd+QICWFssScUiDPyAANODgHuAcr6dsluGUsmvKAvaDb oeLtrCNsDYy/jLsYOTkkBEwkDm3pYYSwxSQu3FvPBmILCSxhlJi3VaKLkQvIbmSSuD9/PRNI gk1AU+Lv5ptgRSIC3hJzVvcxghQxC6xnlJj6+C87SEJYIFRi8axvzCA2i4CqxL2nU8E28Ao4 Sfzc8p0JYpucxM1znWA1nALOEudvfAGKcwBtc5K4Nkt2AiPvAkaGVYwiqaXFuem5xUZ6xYm5 xaV56XrJ+bmbGIHhuu3Yzy07GLveBR9iFOBgVOLh3XGiIUKINbGsuDL3EKMEB7OSCG/P+sYI Id6UxMqq1KL8+KLSnNTiQ4ymQDdNZJYSTc4HxlJeSbyhiaG5paGRsYWFuZGRkjjv1A9XwoUE 0hNLUrNTUwtSi2D6mDg4pRoY83WjX0Vm64onfj2iX9cpYrv9swCDn/085dSPE9ounDvJuOD0 2dMbpCuf7f4943aIKY9Pz07BvbsvVYY+zL0cc6Ds3qNNPe6NZju9khPOH0ht6hX71vLhmM9C zgM29b5hcQuiSxaFCl3iDZPcsnACz4Sph46yu90J5Z1nVx35n7VFpyGPa8IxJZbijERDLeai 4kQAFvmtKm0CAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170120073857eucas1p2669acdcb12a64294bccebece4990fb5c 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: 20170120073857eucas1p2669acdcb12a64294bccebece4990fb5c X-RootMTR: 20170120073857eucas1p2669acdcb12a64294bccebece4990fb5c References: <1484897930-1275-1-git-send-email-a.hajda@samsung.com> 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 | 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 + #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; @@ -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