From patchwork Wed Jul 9 12:37:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 33302 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qg0-f69.google.com (mail-qg0-f69.google.com [209.85.192.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4D38D203F4 for ; Wed, 9 Jul 2014 12:39:15 +0000 (UTC) Received: by mail-qg0-f69.google.com with SMTP id j107sf17051210qga.0 for ; Wed, 09 Jul 2014 05:39:15 -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=SyB7oR9bPACW1OjmL8niuN/SQeVcZBebBqkWLudn5Wg=; b=h5YwdfApNcVK1Oyh95eC6qtJGuI2pl1peLbiK0wnKxclubQK8ANJv/eCfaFGmS4L5f k2pXY85PeZGYgoc592tK0cobKYXD3CpmYZJq9b+qDXvWoA3GY+khWinMReXKZ7EshgBH l72DMasSGOSPK90ZlB3lkzfITP/9KUTpz7rDCcd7eBmFYpS1eEnb8kOSDK/u+m8G3utN FmJXo2xplb1mdbCgP7UZtzFvNt2y4PcdvY2v4FC5N0o0AJQltwWEHeRikkLUCEtytnRO 7pjebcsHK6EGIQ+MebYQfmbhEYBb0ZoTbXwe9Lf+9cE2CEZD+Jnk3CMON9g0nu/kzk8c mr9w== X-Gm-Message-State: ALoCoQk+lG3WEjpgq6BcUfLrjOJAFwyWt9UJmDK1c/ikH3r+fcXOER46OLErzmeCZ3UNEHQtRqld X-Received: by 10.58.219.105 with SMTP id pn9mr20381950vec.30.1404909555059; Wed, 09 Jul 2014 05:39:15 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.107.198 with SMTP id h64ls2611516qgf.66.gmail; Wed, 09 Jul 2014 05:39:15 -0700 (PDT) X-Received: by 10.58.29.16 with SMTP id f16mr40358494veh.23.1404909554985; Wed, 09 Jul 2014 05:39:14 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id yr5si21398557vdb.14.2014.07.09.05.39.14 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 09 Jul 2014 05:39:14 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id il7so6757194vcb.40 for ; Wed, 09 Jul 2014 05:39:14 -0700 (PDT) X-Received: by 10.52.158.198 with SMTP id ww6mr23494559vdb.17.1404909554883; Wed, 09 Jul 2014 05:39:14 -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 tc5csp44147vcb; Wed, 9 Jul 2014 05:39:14 -0700 (PDT) X-Received: by 10.68.133.40 with SMTP id oz8mr1342299pbb.132.1404909554048; Wed, 09 Jul 2014 05:39:14 -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.13; Wed, 09 Jul 2014 05:39:13 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-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 S1756352AbaGIMjH (ORCPT + 28 others); Wed, 9 Jul 2014 08:39:07 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:36482 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755708AbaGIMjA (ORCPT ); Wed, 9 Jul 2014 08:39:00 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id s69Cc3S0005671; Wed, 9 Jul 2014 07:38:03 -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 s69Cc3U4031737; Wed, 9 Jul 2014 07:38:03 -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:03 -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 s69CbX7p010057; Wed, 9 Jul 2014 07:38:00 -0500 From: Roger Quadros To: , CC: , , , , , , , , , Roger Quadros Subject: [RFC PATCH 08/10] OMAP: GPMC: Introduce APIs to get ECC/BCH results Date: Wed, 9 Jul 2014 15:37:28 +0300 Message-ID: <1404909450-11970-9-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-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@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.181 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 result registers belong to the GPMC controller's register space. Introduce 2 APIs to access the ECC/BCH results. void omap_gpmc_ecc_get_result(int length, u32 *result); void omap_gpmc_ecc_get_bch_result(int length, u8 sector, u32 *result); The first one is to get the Hamming code ECC result registers and the second one is to get the BCH ECC result registers. Signed-off-by: Roger Quadros --- arch/arm/mach-omap2/gpmc.c | 97 +++++++++++++++++++++++++++++++++++++++--- include/linux/omap-gpmc-nand.h | 11 +++++ 2 files changed, 101 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 8befd16..9222244 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -65,6 +65,7 @@ #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc #define GPMC_ECC1_RESULT 0x200 +#define GPMC_ECC9_RESULT 0x220 #define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */ #define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */ #define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */ @@ -83,6 +84,7 @@ #define GPMC_CS0_OFFSET 0x60 #define GPMC_CS_SIZE 0x30 #define GPMC_BCH_SIZE 0x10 +#define GPMC_BCH_NUM 7 /* Max no. of BCH registers 0-6 */ #define GPMC_MEM_END 0x3FFFFFFF @@ -96,9 +98,10 @@ #define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf) #define GPMC_REVISION_MINOR(l) (l & 0xf) -#define GPMC_HAS_WR_ACCESS 0x1 -#define GPMC_HAS_WR_DATA_MUX_BUS 0x2 -#define GPMC_HAS_MUX_AAD 0x4 +#define GPMC_HAS_WR_ACCESS BIT(0) +#define GPMC_HAS_WR_DATA_MUX_BUS BIT(1) +#define GPMC_HAS_MUX_AAD BIT(2) +#define GPMC_HAS_BCH BIT(3) #define GPMC_NR_WAITPINS 4 @@ -185,6 +188,7 @@ static DEFINE_SPINLOCK(gpmc_mem_lock); static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); static unsigned int gpmc_cs_num = GPMC_CS_NUM; static unsigned int gpmc_nr_waitpins; +static unsigned int gpmc_bch_num = GPMC_BCH_NUM; static struct device *gpmc_dev; static int gpmc_irq; static resource_size_t phys_base, mem_size; @@ -198,6 +202,7 @@ struct gpmc_nand_reg { }; static struct gpmc_nand_reg gpmc_nand_reg_map[GPMC_CS_NUM]; +void __iomem *gpmc_bch_reg_map[GPMC_BCH_NUM][GPMC_BCH_NUM_REMAINDER]; static struct clk *gpmc_l3_clk; @@ -205,7 +210,7 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev); static void gpmc_fill_nand_reg_map(void) { - int i; + int i, j; for (i = 0; i < gpmc_cs_num; i++) { gpmc_nand_reg_map[i].command = gpmc_base + GPMC_CS0_OFFSET + @@ -215,6 +220,28 @@ static void gpmc_fill_nand_reg_map(void) gpmc_nand_reg_map[i].data = gpmc_base + GPMC_CS0_OFFSET + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * i; } + + if (!(gpmc_capability & GPMC_HAS_BCH)) + return; + + + for (i = 0; i < 4; i++) { + for (j = 0; j < 8; j++) { + gpmc_bch_reg_map[i][j] = gpmc_base + + GPMC_ECC_BCH_RESULT_0 + + i * 4 + GPMC_BCH_SIZE * j; + } + } + + /* 2nd for loop for BCH4 onwards due to non-consecutive address */ + for (i = 4; i < gpmc_bch_num; i++) { + for (j = 0; j < 8; j++) { + gpmc_bch_reg_map[i][j] = gpmc_base + + GPMC_ECC_BCH_RESULT_4 + + (i - 4) * 4 + + GPMC_BCH_SIZE * j; + } + } } static void gpmc_write_reg(int idx, u32 val) @@ -1738,10 +1765,17 @@ static int gpmc_probe(struct platform_device *pdev) * - OMAP3xxx = 5.0 * - OMAP44xx/54xx/AM335x = 6.0 */ - if (GPMC_REVISION_MAJOR(l) > 0x4) - gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS; - if (GPMC_REVISION_MAJOR(l) > 0x5) + if (GPMC_REVISION_MAJOR(l) >= 5) { + gpmc_capability = GPMC_HAS_WR_ACCESS | + GPMC_HAS_WR_DATA_MUX_BUS | GPMC_HAS_BCH; + gpmc_bch_num = 4; + } + + if (GPMC_REVISION_MAJOR(l) >= 6) { gpmc_capability |= GPMC_HAS_MUX_AAD; + gpmc_bch_num = GPMC_BCH_NUM; + } + dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), GPMC_REVISION_MINOR(l)); @@ -2188,3 +2222,52 @@ void omap_gpmc_ecc_configure_enable(int cs, bool ecc16, u8 ecc_size0, val |= GPMC_ECC_CONFIG_ECCENABLE; gpmc_write_reg(GPMC_ECC_CONFIG, val); } + +/** + * omap_gpmc_ecc_get_result - reads out the Hamming code ECC result registers + * + * @length: Number of 32-bit registers to read + * @result: pointer to 32-bit buffer where results should be copied into + */ +void omap_gpmc_ecc_get_result(int length, u32 *result) +{ + u32 reg_addr; + int i; + + if (!gpmc_dev) + return; + + reg_addr = GPMC_ECC1_RESULT; + for (i = 0; i < length; i++) { + *result++ = gpmc_read_reg(reg_addr); + reg_addr += 4; + /* Don't read past ECC_RESULT region */ + if (reg_addr > GPMC_ECC9_RESULT) + break; + } +} + +/** + * omap_gpmc_ecc_get_bch_result - reads out the BCH result registers + * + * @length: Number of 32-bit registers to read + * @sector: Which sector's results to read (0 to 7) + * @result: pointer to 32-bit buffer where results should be copied into + */ +void omap_gpmc_ecc_get_bch_result(int length, u8 sector, u32 *result) +{ + int i; + + if (!gpmc_dev) + return; + + if (sector > GPMC_BCH_NUM_REMAINDER) + return; + + /* Don't read past BCH_RESULT region */ + if (length > gpmc_bch_num) + length = gpmc_bch_num; + + for (i = 0; i < length; i++) + *result++ = readl_relaxed(gpmc_bch_reg_map[i][sector]); +} diff --git a/include/linux/omap-gpmc-nand.h b/include/linux/omap-gpmc-nand.h index f08cd05..d0ef165 100644 --- a/include/linux/omap-gpmc-nand.h +++ b/include/linux/omap-gpmc-nand.h @@ -43,6 +43,8 @@ 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); +void omap_gpmc_ecc_get_result(int length, u32 *result); +void omap_gpmc_ecc_get_bch_result(int length, u8 sector, u32 *result); #else static inline u32 omap_gpmc_read_reg(int cs, enum omap_gpmc_reg reg) { @@ -87,6 +89,15 @@ static inline void omap_gpmc_ecc_configure_enable(int cs, bool ecc16, { } +static inline void omap_gpmc_ecc_get_result(int length, u32 *result) +{ +} + +static inline void omap_gpmc_ecc_get_bch_result(int length, u8 sector, + u32 *result) +{ +} + #endif /* Prefetch/Write-post Engine */