From patchwork Wed Jul 9 12:37:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 33300 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qa0-f72.google.com (mail-qa0-f72.google.com [209.85.216.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id EEE4D203F4 for ; Wed, 9 Jul 2014 12:39:12 +0000 (UTC) Received: by mail-qa0-f72.google.com with SMTP id s7sf4631838qap.11 for ; Wed, 09 Jul 2014 05:39:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type; bh=sr2rlyoBC7qHw+KWlgfxD9JHV+1iJBusChmoKaUO8CY=; b=jr6Fa6zW9TkgBkCsUnROtqnAnPUfJPLH2sqLwQ3xoz0GnBB5EfbYUZYWn/3OqqHDfH KZzcAGc3E+wc9CaiUD+pXu70D0eUbkx8+XD/OBOidjNZKDiCsogVAd+8ebPM91D5hFWG g8XrPJT6LBq15WD7+8/9SzQ4D9Ol2bxGCjg+hAqZynZ6PUTv2JT5+46egG1ypA469lOb EEcOcvDDZHFqkd4vQdGAsxXcDtpkOmv0sG2uaFnRHVuUKpcD0Llyyx39UCLW+wDDFuLX uJtV14KZ298DUxidGcF7TA36/pr5FrC9o6wWZwhGVM48kAIvLVx0irWtQfovGIuTPGG2 tRqw== X-Gm-Message-State: ALoCoQmOG6Q4JdK2W6waJw0ktoMpk5h+/u1cc7QafQpjJjYgsY0Ppcqkt7YgfwQX5ISVlG5Km6yZ X-Received: by 10.236.171.234 with SMTP id r70mr17326670yhl.45.1404909552836; Wed, 09 Jul 2014 05:39:12 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.100.235 with SMTP id s98ls2528299qge.79.gmail; Wed, 09 Jul 2014 05:39:12 -0700 (PDT) X-Received: by 10.220.164.198 with SMTP id f6mr165252vcy.51.1404909552737; Wed, 09 Jul 2014 05:39:12 -0700 (PDT) Received: from mail-vc0-f171.google.com (mail-vc0-f171.google.com [209.85.220.171]) by mx.google.com with ESMTPS id wv1si21388075vdb.80.2014.07.09.05.39.12 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 09 Jul 2014 05:39:12 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.171 as permitted sender) client-ip=209.85.220.171; Received: by mail-vc0-f171.google.com with SMTP id id10so6791243vcb.2 for ; Wed, 09 Jul 2014 05:39:12 -0700 (PDT) X-Received: by 10.221.34.13 with SMTP id sq13mr16052190vcb.16.1404909552610; Wed, 09 Jul 2014 05:39:12 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp44140vcb; Wed, 9 Jul 2014 05:39:12 -0700 (PDT) X-Received: by 10.68.138.227 with SMTP id qt3mr41126592pbb.6.1404909551702; Wed, 09 Jul 2014 05:39:11 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j6si7297480pdk.202.2014.07.09.05.39.11; Wed, 09 Jul 2014 05:39:11 -0700 (PDT) Received-SPF: none (google.com: linux-omap-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756091AbaGIMiw (ORCPT + 6 others); Wed, 9 Jul 2014 08:38:52 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:60429 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755708AbaGIMiu (ORCPT ); Wed, 9 Jul 2014 08:38:50 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id s69Cc0rD030414; Wed, 9 Jul 2014 07:38:00 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id s69Cc0FW031623; Wed, 9 Jul 2014 07:38:00 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Wed, 9 Jul 2014 07:38:00 -0500 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id s69CbX7o010057; Wed, 9 Jul 2014 07:37:57 -0500 From: Roger Quadros To: , CC: , , , , , , , , , Roger Quadros Subject: [RFC PATCH 07/10] OMAP: GPMC: Introduce APIs for Configuring ECC Engine Date: Wed, 9 Jul 2014 15:37:27 +0300 Message-ID: <1404909450-11970-8-git-send-email-rogerq@ti.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1404909450-11970-1-git-send-email-rogerq@ti.com> References: <1404909450-11970-1-git-send-email-rogerq@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: rogerq@ti.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.171 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Even though the ECC/BCH engine is meant for exclusive use by the OMAP NAND controller, the ECC/BCH registers belong to the GPMC controller's register space Add omap_gpmc_ecc_configure_enable() and omap_gpmc_ecc_disable() to manage the ECC engine. OMAP NAND driver must use these APIs instead of directly accessing the ECC Engine registers. Signed-off-by: Roger Quadros --- arch/arm/mach-omap2/gpmc.c | 109 ++++++++++++++++++++++++++++++++++++----- include/linux/omap-gpmc-nand.h | 25 ++++++++++ 2 files changed, 121 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 43e2a9d..8befd16 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -73,19 +73,6 @@ #define GPMC_ECC_BCH_RESULT_5 0x304 /* not available on OMAP2 */ #define GPMC_ECC_BCH_RESULT_6 0x308 /* not available on OMAP2 */ -/* GPMC ECC control settings */ -#define GPMC_ECC_CTRL_ECCCLEAR 0x100 -#define GPMC_ECC_CTRL_ECCDISABLE 0x000 -#define GPMC_ECC_CTRL_ECCREG1 0x001 -#define GPMC_ECC_CTRL_ECCREG2 0x002 -#define GPMC_ECC_CTRL_ECCREG3 0x003 -#define GPMC_ECC_CTRL_ECCREG4 0x004 -#define GPMC_ECC_CTRL_ECCREG5 0x005 -#define GPMC_ECC_CTRL_ECCREG6 0x006 -#define GPMC_ECC_CTRL_ECCREG7 0x007 -#define GPMC_ECC_CTRL_ECCREG8 0x008 -#define GPMC_ECC_CTRL_ECCREG9 0x009 - #define GPMC_CONFIG2_CSEXTRADELAY BIT(7) #define GPMC_CONFIG3_ADVEXTRADELAY BIT(7) #define GPMC_CONFIG4_OEEXTRADELAY BIT(7) @@ -129,6 +116,28 @@ #define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) +/* GPMC ECC config */ +#define GPMC_ECC_CONFIG_ECCENABLE BIT(0) +#define GPMC_ECC_CONFIG_ECCCS_MASK GENMASK(3, 1) +#define GPMC_ECC_CONFIG_ECCCS_SHIFT 1 +#define GPMC_ECC_CONFIG_ECCNSECTOR_MASK GENMASK(6, 4) +#define GPMC_ECC_CONFIG_ECCNSECTOR_SHIFT 4 +#define GPMC_ECC_CONFIG_ECC16B BIT(7) +#define GPMC_ECC_CONFIG_ECCWRAPMODE_MASK GENMASK(11, 8) +#define GPMC_ECC_CONFIG_ECCWRAPMODE_SHIFT 8 +#define GPMC_ECC_CONFIG_ECCBCHTSEL_MASK GENMASK(13, 12) +#define GPMC_ECC_CONFIG_ECCBCHTSEL_SHIFT 12 +#define GPMC_ECC_CONFIG_ECCALGBCH BIT(16) + +/* GPMC ECC control */ +#define GPMC_ECC_CONTROL_ECCCLEAR BIT(8) +#define GPMC_ECC_CONTROL_ECCPOINTER_MASK GENMASK(3, 0) +#define GPMC_ECC_CONTROL_ECCPOINTER_SHIFT 0 + +/* GPMC ECC size */ +#define GPMC_ECC_SIZE_ECCSIZE0_SHIFT 12 +#define GPMC_ECC_SIZE_ECCSIZE1_SHIFT 22 + /* XXX: Only NAND irq has been considered,currently these are the only ones used */ #define GPMC_NR_IRQ 2 @@ -2105,3 +2114,77 @@ u32 omap_gpmc_get_prefetch_fifo_count(void) count = GPMC_PREFETCH_STATUS_FIFO_CNT(count); return count; } + +/** + * omap_gpmc_ecc_disable - Disables the ECC engine + * but doesn't clear the ECC result registers. + */ +void omap_gpmc_ecc_disable(void) +{ + u32 val; + + /* Disable ECC engine if running */ + val = gpmc_read_reg(GPMC_ECC_CONFIG); + if (val & GPMC_ECC_CONFIG_ECCENABLE) { + val &= ~GPMC_ECC_CONFIG_ECCENABLE; + gpmc_write_reg(GPMC_ECC_CONFIG, val); + } +} + +/** + * omap_gpmc_ecc_configure_enable - Configures and enables the ECC-BCH engine + * + * @cs: chip select number + * @ecc16: true for 16-bit ECC column, false for 8-bit ECC columna + * @ecc_size0: This value is written to ECCSIZE0 of GPMC_ECC_SIZE_CONFIG reg. + * @ecc_size1: This value is written to ECCSIZE1 of GPMC_ECC_SIZE_CONFIG reg. + * @use_bch: true for BCH algorithm, false for 1-bit Hamming code algorithm + * @bch_type: enum omap_gpmc_bch_type, 4-bit, 8-bit or 16-bit BCH error + * correction cabability. Ignored if use_bch is false. + * @bch_sectors: No. of sectors to process with BCH. Ignored if use_bch false. + * @bch_wrap_mode: pre defined spare area defination for BCH calculation. + * Ignored if use_bch is false + */ +void omap_gpmc_ecc_configure_enable(int cs, bool ecc16, u8 ecc_size0, + u8 ecc_size1, bool use_bch, + enum omap_gpmc_bch_type bch_type, + u8 bch_sectors, u8 bch_wrap_mode) +{ + u32 val, valx; + + /* Disable ECC engine if running */ + omap_gpmc_ecc_disable(); + + /* Clear all ECC/BCH result registers */ + gpmc_write_reg(GPMC_ECC_CONTROL, GPMC_ECC_CONTROL_ECCCLEAR); + + /* ECC size */ + val = (ecc_size1 << GPMC_ECC_SIZE_ECCSIZE1_SHIFT) | + (ecc_size0 << GPMC_ECC_SIZE_ECCSIZE0_SHIFT); + gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val); + + /* ECC config */ + val = (cs << GPMC_ECC_CONFIG_ECCCS_SHIFT) & GPMC_ECC_CONFIG_ECCCS_MASK; + + if (ecc16) + val |= GPMC_ECC_CONFIG_ECC16B; + + if (use_bch) { + val |= GPMC_ECC_CONFIG_ECCALGBCH; + val |= (bch_type << GPMC_ECC_CONFIG_ECCBCHTSEL_SHIFT) & + GPMC_ECC_CONFIG_ECCBCHTSEL_MASK; + val |= (bch_sectors << GPMC_ECC_CONFIG_ECCNSECTOR_SHIFT) & + GPMC_ECC_CONFIG_ECCNSECTOR_MASK; + val |= (bch_wrap_mode << GPMC_ECC_CONFIG_ECCWRAPMODE_SHIFT) & + GPMC_ECC_CONFIG_ECCWRAPMODE_MASK; + } else { + /* Reset ECC result pointer to 1 */ + valx = (1 << GPMC_ECC_CONTROL_ECCPOINTER_SHIFT) & + GPMC_ECC_CONTROL_ECCPOINTER_MASK; + gpmc_write_reg(GPMC_ECC_CONTROL, valx); + } + + /* Enable ECC engine */ + val |= GPMC_ECC_CONFIG_ECCENABLE; + gpmc_write_reg(GPMC_ECC_CONFIG, val); +} diff --git a/include/linux/omap-gpmc-nand.h b/include/linux/omap-gpmc-nand.h index c445d89..f08cd05 100644 --- a/include/linux/omap-gpmc-nand.h +++ b/include/linux/omap-gpmc-nand.h @@ -23,6 +23,12 @@ enum omap_gpmc_reg { OMAP_GPMC_NAND_DATA, }; +enum omap_gpmc_bch_type { + OMAP_GPMC_BCH4, + OMAP_GPMC_BCH8, + OMAP_GPMC_BCH16, +}; + #ifdef CONFIG_ARCH_OMAP2PLUS u32 omap_gpmc_read_reg(int cs, enum omap_gpmc_reg reg); void omap_gpmc_write_reg(int cs, enum omap_gpmc_reg reg, u32 val); @@ -32,6 +38,11 @@ int omap_gpmc_prefetch_start(int cs, int fifo_th, bool dma, int omap_gpmc_prefetch_stop(int cs); u32 omap_gpmc_get_prefetch_count(void); u32 omap_gpmc_get_prefetch_fifo_count(void); +void omap_gpmc_ecc_disable(void); +void omap_gpmc_ecc_configure_enable(int cs, bool ecc16, u8 ecc_size0, + u8 ecc_size1, bool use_bch, + enum omap_gpmc_bch_type bch_type, + u8 bch_sectors, u8 bch_wrap_mode); #else static inline u32 omap_gpmc_read_reg(int cs, enum omap_gpmc_reg reg) { @@ -62,6 +73,20 @@ static inline u32 omap_gpmc_get_prefetch_fifo_count(void) { return 0; } + +static inline void omap_gpmc_ecc_disable(void) +{ +} + +static inline void omap_gpmc_ecc_configure_enable(int cs, bool ecc16, + u8 ecc_size0, u8 ecc_size1, + bool use_bch, + enum omap_gpmc_bch_type bch_type, + u8 bch_sectors, + u8 bch_wrap_mode) +{ +} + #endif /* Prefetch/Write-post Engine */