From patchwork Wed Aug 12 15:12:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 7002781 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id F26919F39D for ; Wed, 12 Aug 2015 15:12:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 02395204EC for ; Wed, 12 Aug 2015 15:12:36 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 0565E204DE for ; Wed, 12 Aug 2015 15:12:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 477636EB9D; Wed, 12 Aug 2015 08:12:34 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yk0-f171.google.com (mail-yk0-f171.google.com [209.85.160.171]) by gabe.freedesktop.org (Postfix) with ESMTPS id CBFC96EB9D for ; Wed, 12 Aug 2015 08:12:32 -0700 (PDT) Received: by ykdz80 with SMTP id z80so16436645ykd.2 for ; Wed, 12 Aug 2015 08:12:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=fWgx+VwqDHeasDbIRwFxjKWrXNV/MSnodJxSveW3sLM=; b=Ea+lU7ZMN44AwSIfwcNiQswU1daNAASJ3fkF9wjPljzp/oMGtsnepOHig0VGbIvt9L 6wV+/kmeHgTjirdSZouUdmoEjN2VcWdkIZL1hvuP9t7OEhSC6B5NYq4+8rnL85CeYObo Ct2v4u/QkJ/sxoys6hEOYcUO+RGb11f8wishM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fWgx+VwqDHeasDbIRwFxjKWrXNV/MSnodJxSveW3sLM=; b=X0q6+FcQDROCZS+t836fdI7kDYF5fKB/SUIUzxLAspbi0dH53vNR7tjTzWdFMCUdAC kJEZowC4Tmz4sWhUybnA9uNMcTzdRWWhwt9U4CGx1iU4Gu/KU8/aUh9L9wGWWrxViYhp JrSTT+4OKOdQ0mtBY57uNcsz5nSr4hf2YBFYmFo246mEYbETM7Aj3cWf8D50KBZrBQ4M KJr4242eja4zAPNndW2qB2H3PflFRqOIlAKwQE1EDPld3jBHQcWWl81oDmJe0MQOGasa tUMQIMmX4cJ5QLWoHROZlOHFR/pz70/c7jz+KkPJGDHUxrhh1B1JGpKR9IZoVyf10Ild g7iQ== X-Gm-Message-State: ALoCoQl4cKZTQXSf2hcEgxM2Fp321Jlkkl3jwvcmfX16HzOj8rE8Bg/wexH/vCVGX4zWA6L4toFb X-Received: by 10.170.61.70 with SMTP id d67mr19018575ykd.121.1439392352046; Wed, 12 Aug 2015 08:12:32 -0700 (PDT) Received: from billyjoel.roam.corp.google.com (cpe-75-189-128-87.nc.res.rr.com. [75.189.128.87]) by smtp.gmail.com with ESMTPSA id r129sm4868152ywd.26.2015.08.12.08.12.30 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 12 Aug 2015 08:12:31 -0700 (PDT) From: Sean Paul To: airlied@linux.ie, thierry.reding@gmail.com, dri-devel@lists.freedesktop.org Subject: [PATCH 2/2] drm: mipi: Add software-calculated ECC & CRC flags Date: Wed, 12 Aug 2015 11:12:20 -0400 Message-Id: <1439392340-17130-2-git-send-email-seanpaul@chromium.org> X-Mailer: git-send-email 2.5.0.rc2.392.g76e840b In-Reply-To: <1439392340-17130-1-git-send-email-seanpaul@chromium.org> References: <1439392340-17130-1-git-send-email-seanpaul@chromium.org> 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-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Allow ECC and CRC for a packet to be calculated in software. Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_mipi_dsi.c | 56 ++++++++++++++++++++++++++++++++++++++++-- include/drm/drm_mipi_dsi.h | 6 +++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 2d5ca8ee..77390e6 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -312,6 +312,54 @@ bool mipi_dsi_packet_format_is_long(u8 type) } EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); +#define BIT_VAL(x, nr) ((x & BIT(nr)) >> nr) +#define XOR13(x, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13) \ + (BIT_VAL(x, b1) ^ BIT_VAL(x, b2) ^ BIT_VAL(x, b3) ^ BIT_VAL(x, b4) ^ \ + BIT_VAL(x, b5) ^ BIT_VAL(x, b6) ^ BIT_VAL(x, b7) ^ BIT_VAL(x, b8) ^ \ + BIT_VAL(x, b9) ^ BIT_VAL(x, b10) ^ BIT_VAL(x, b11) ^ \ + BIT_VAL(x, b12) ^ BIT_VAL(x, b13)) +#define XOR14(x, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14) \ + (XOR13(x, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13) ^ \ + BIT_VAL(x, b14)) + +static u8 mipi_dsi_calculate_ecc(const u8 *header) +{ + u8 ecc; + u32 v = header[2] << 16 | header[1] << 8 | header[0]; + + ecc = XOR14(v, 0, 1, 2, 4, 5, 7, 10, 11, 13, 16, 20, 21, 22, 23) | + XOR14(v, 0, 1, 3, 4, 6, 8, 10, 12, 14, 17, 20, 21, 22, 23) << 1 | + XOR13(v, 0, 2, 3, 5, 6, 9, 11, 12, 15, 18, 20, 21, 22) << 2 | + XOR13(v, 1, 2, 3, 7, 8, 9, 13, 14, 15, 19, 20, 21, 23) << 3 | + XOR13(v, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 22, 23) << 4 | + XOR13(v, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23) << 5; + return ecc; +} + +static u16 mipi_dsi_calculate_crc(struct mipi_dsi_packet *packet) +{ + static const u16 gen_code = 0x8408; + size_t i, j; + u16 ret = 0xFFFF; + + /* If the packet is zero-length, return 0xFFFF as the checksum */ + if (packet->payload_length == 0) + return 0xFFFF; + + for (i = 0; i < packet->payload_length; i++) { + u8 d = packet->payload[i]; + + for (j = 0; j < 8; j++) { + if (((ret & 1) ^ (d & 1)) > 0) + ret = ((ret >> 1) & 0x7FFF) ^ gen_code; + else + ret = (ret >> 1) & 0x7FFF; + d = (d >> 1) & 0x7F; + } + } + return ret; +} + /** * mipi_dsi_create_packet - create a packet from a message according to the * DSI protocol @@ -337,8 +385,6 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, memset(packet, 0, sizeof(*packet)); packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); - /* TODO: compute ECC if hardware support is not available */ - /* * Long write packets contain the word count in header bytes 1 and 2. * The payload follows the header and is word count bytes long. @@ -359,8 +405,14 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; } + if (msg->flags & MIPI_DSI_MSG_SW_ECC) + packet->header[3] = mipi_dsi_calculate_ecc(packet->header); + packet->size = sizeof(packet->header) + packet->payload_length; + if (msg->flags & MIPI_DSI_MSG_SW_CRC) + packet->checksum = mipi_dsi_calculate_crc(packet); + return 0; } EXPORT_SYMBOL(mipi_dsi_create_packet); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index f1d8d0d..49d52ba 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -21,6 +21,10 @@ struct mipi_dsi_device; #define MIPI_DSI_MSG_REQ_ACK BIT(0) /* use Low Power Mode to transmit message */ #define MIPI_DSI_MSG_USE_LPM BIT(1) +/* calculate ECC in software */ +#define MIPI_DSI_MSG_SW_ECC BIT(2) +/* calculate checksum in software */ +#define MIPI_DSI_MSG_SW_CRC BIT(3) /** * struct mipi_dsi_msg - read/write DSI buffer @@ -54,12 +58,14 @@ bool mipi_dsi_packet_format_is_long(u8 type); * Packet Data, and ECC) * @payload_length: number of bytes in the payload * @payload: a pointer to a buffer containing the payload, if any + * @checksum: the CRC of the payload (only applies to long packets) */ struct mipi_dsi_packet { size_t size; u8 header[4]; size_t payload_length; const u8 *payload; + u16 checksum; }; int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,