From patchwork Wed Jul 9 12:37:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 33301 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f197.google.com (mail-qc0-f197.google.com [209.85.216.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5A584203F4 for ; Wed, 9 Jul 2014 12:39:14 +0000 (UTC) Received: by mail-qc0-f197.google.com with SMTP id i8sf24831566qcq.4 for ; Wed, 09 Jul 2014 05:39:14 -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=o8R1aLwL06a8xalR4OQyGCGdF4TuFGMdNrXiMVpQ8ag=; b=jEscNnPZwyvCbvoFzPF4I1dWKwl0yB4LgCx2X1htNDD7rHIEIu+JKIZCv9AoIcLLQK DQyYP6qC7lDUTigVDtf9XywFXRu4IRPCoOxUQEX75FwsKwmVQA2gIwE8vdXiDnpsI2QE AWGnyR4kLe8np7vXOM5CPCqmwdb1LiAvCeOisW5LPqSx/WHdZLVO7roUEpOMvqBsZDof PqVpmkHfo/0eO186Mo7S2rNOgv2S3vuenCgKLszLagqykUyWBkibqWGXohkUggZsIC/7 loagqJZScuV7jvvKwnlh5SHLRXdhQK4DsvBFzw2YQLult2vwIqzR5pkaqEgcW+kyJdH/ 4a/Q== X-Gm-Message-State: ALoCoQnZAhZyyVFvAw2Tnq+bmpqzfw+lsgmROERtU9TOQfB4rCM8yE/quI9Srz6POiwySuCuyFK6 X-Received: by 10.236.202.143 with SMTP id d15mr17312524yho.18.1404909554227; Wed, 09 Jul 2014 05:39:14 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.101.205 with SMTP id u71ls2554693qge.52.gmail; Wed, 09 Jul 2014 05:39:14 -0700 (PDT) X-Received: by 10.58.152.234 with SMTP id vb10mr39513395veb.21.1404909554152; Wed, 09 Jul 2014 05:39:14 -0700 (PDT) Received: from mail-vc0-f179.google.com (mail-vc0-f179.google.com [209.85.220.179]) by mx.google.com with ESMTPS id dj5si21436262vcb.21.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.179 as permitted sender) client-ip=209.85.220.179; Received: by mail-vc0-f179.google.com with SMTP id id10so6898256vcb.10 for ; Wed, 09 Jul 2014 05:39:14 -0700 (PDT) X-Received: by 10.220.137.145 with SMTP id w17mr170926vct.47.1404909554062; 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 tc5csp44145vcb; Wed, 9 Jul 2014 05:39:13 -0700 (PDT) X-Received: by 10.68.224.198 with SMTP id re6mr41392813pbc.8.1404909553129; Wed, 09 Jul 2014 05:39:13 -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.12; Wed, 09 Jul 2014 05:39:12 -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 S1755825AbaGIMjE (ORCPT + 28 others); Wed, 9 Jul 2014 08:39:04 -0400 Received: from arroyo.ext.ti.com ([192.94.94.40]:38274 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755762AbaGIMjA (ORCPT ); Wed, 9 Jul 2014 08:39:00 -0400 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id s69Cc7SP006295; Wed, 9 Jul 2014 07:38:07 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s69Cc7cR006667; Wed, 9 Jul 2014 07:38:07 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.3.174.1; Wed, 9 Jul 2014 07:38:06 -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 s69CbX7q010057; Wed, 9 Jul 2014 07:38:03 -0500 From: Roger Quadros To: , CC: , , , , , , , , , Roger Quadros Subject: [RFC PATCH 09/10] mtd: nand: omap: Use GPMC APIs for accessing ECC/BCH engine Date: Wed, 9 Jul 2014 15:37:29 +0300 Message-ID: <1404909450-11970-10-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.179 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: , Don't access the ECC/BCH engine registers directly as they belong to the GPMC controller's register space. Use the relevant GPMC APIs instead. Signed-off-by: Roger Quadros --- drivers/mtd/nand/omap2.c | 191 +++++++++++++++++++---------------------------- 1 file changed, 76 insertions(+), 115 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 420ef0b..6b0f953 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -865,16 +865,10 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); u32 val; - val = readl(info->reg.gpmc_ecc_config); - if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) - return -EINVAL; - /* read ecc result */ - val = readl(info->reg.gpmc_ecc1_result); + omap_gpmc_ecc_get_result(1, &val); *ecc_code++ = val; /* P128e, ..., P1e */ *ecc_code++ = val >> 16; /* P128o, ..., P1o */ /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ @@ -894,34 +888,22 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) mtd); struct nand_chip *chip = mtd->priv; unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; - u32 val; - - /* clear ecc and enable bits */ - val = ECCCLEAR | ECC1; - writel(val, info->reg.gpmc_ecc_control); + u32 ecc_size0; - /* program ecc and result sizes */ - val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | - ECC1RESULTSIZE); - writel(val, info->reg.gpmc_ecc_size_config); + ecc_size0 = (info->nand.ecc.size >> 1) - 1; switch (mode) { case NAND_ECC_READ: case NAND_ECC_WRITE: - writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); + omap_gpmc_ecc_configure_enable(info->gpmc_cs, dev_width, + ecc_size0, 0, false, + 0, 0, 0); break; case NAND_ECC_READSYN: - writel(ECCCLEAR, info->reg.gpmc_ecc_control); - break; - default: - dev_info(&info->pdev->dev, - "error: unrecognized Mode[%d]!\n", mode); + /* Disable the engine, but don't clear ECC results */ + omap_gpmc_ecc_disable(); break; } - - /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ - val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); - writel(val, info->reg.gpmc_ecc_config); } /** @@ -993,20 +975,20 @@ static int omap_dev_ready(struct mtd_info *mtd) */ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) { - unsigned int bch_type; + enum omap_gpmc_bch_type bch_type; unsigned int dev_width, nsectors; struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); enum omap_ecc ecc_opt = info->ecc_opt; struct nand_chip *chip = mtd->priv; - u32 val, wr_mode; + u32 wr_mode; unsigned int ecc_size1, ecc_size0; /* GPMC configurations for calculating ECC */ nsectors = chip->ecc.steps; switch (ecc_opt) { case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: - bch_type = 0; + bch_type = OMAP_GPMC_BCH4; if (mode == NAND_ECC_READ) { wr_mode = BCH_WRAPMODE_6; ecc_size0 = BCH_ECC_SIZE0; @@ -1018,7 +1000,7 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) } break; case OMAP_ECC_BCH4_CODE_HW: - bch_type = 0; + bch_type = OMAP_GPMC_BCH4; if (mode == NAND_ECC_READ) { wr_mode = BCH_WRAPMODE_1; ecc_size0 = BCH4R_ECC_SIZE0; @@ -1030,7 +1012,7 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) } break; case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: - bch_type = 1; + bch_type = OMAP_GPMC_BCH8; if (mode == NAND_ECC_READ) { wr_mode = BCH_WRAPMODE_6; ecc_size0 = BCH_ECC_SIZE0; @@ -1042,7 +1024,7 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) } break; case OMAP_ECC_BCH8_CODE_HW: - bch_type = 1; + bch_type = OMAP_GPMC_BCH8; if (mode == NAND_ECC_READ) { wr_mode = BCH_WRAPMODE_1; ecc_size0 = BCH8R_ECC_SIZE0; @@ -1054,7 +1036,7 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) } break; case OMAP_ECC_BCH16_CODE_HW: - bch_type = 0x2; + bch_type = OMAP_GPMC_BCH16; if (mode == NAND_ECC_READ) { wr_mode = 0x01; ecc_size0 = 52; /* ECC bits in nibbles per sector */ @@ -1069,27 +1051,11 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) return; } - writel(ECC1, info->reg.gpmc_ecc_control); - - /* Configure ecc size for BCH */ - val = (ecc_size1 << ECCSIZE1_SHIFT) | (ecc_size0 << ECCSIZE0_SHIFT); - writel(val, info->reg.gpmc_ecc_size_config); - dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; - /* BCH configuration */ - val = ((1 << 16) | /* enable BCH */ - (bch_type << 12) | /* BCH4/BCH8/BCH16 */ - (wr_mode << 8) | /* wrap mode */ - (dev_width << 7) | /* bus width */ - (((nsectors-1) & 0x7) << 4) | /* number of sectors */ - (info->gpmc_cs << 1) | /* ECC CS */ - (0x1)); /* enable ECC */ - - writel(val, info->reg.gpmc_ecc_config); - - /* Clear ecc and enable bits */ - writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); + omap_gpmc_ecc_configure_enable(info->gpmc_cs, dev_width, + ecc_size0, ecc_size1, true, + bch_type, nsectors - 1, wr_mode); } static u8 bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f}; @@ -1111,11 +1077,10 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, mtd); struct nand_chip *chip = mtd->priv; int eccbytes = info->nand.ecc.bytes; - struct gpmc_nand_regs *gpmc_regs = &info->reg; u8 *ecc_code; - unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4; - u32 val; + unsigned long nsectors; int i, j; + u32 bch_val[7]; nsectors = chip->ecc.steps; for (i = 0; i < nsectors; i++) { @@ -1123,71 +1088,67 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, switch (info->ecc_opt) { case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: case OMAP_ECC_BCH8_CODE_HW: - bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); - bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); - bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]); - bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]); - *ecc_code++ = (bch_val4 & 0xFF); - *ecc_code++ = ((bch_val3 >> 24) & 0xFF); - *ecc_code++ = ((bch_val3 >> 16) & 0xFF); - *ecc_code++ = ((bch_val3 >> 8) & 0xFF); - *ecc_code++ = (bch_val3 & 0xFF); - *ecc_code++ = ((bch_val2 >> 24) & 0xFF); - *ecc_code++ = ((bch_val2 >> 16) & 0xFF); - *ecc_code++ = ((bch_val2 >> 8) & 0xFF); - *ecc_code++ = (bch_val2 & 0xFF); - *ecc_code++ = ((bch_val1 >> 24) & 0xFF); - *ecc_code++ = ((bch_val1 >> 16) & 0xFF); - *ecc_code++ = ((bch_val1 >> 8) & 0xFF); - *ecc_code++ = (bch_val1 & 0xFF); + omap_gpmc_ecc_get_bch_result(4, i, bch_val); + *ecc_code++ = (bch_val[3] & 0xFF); + *ecc_code++ = ((bch_val[2] >> 24) & 0xFF); + *ecc_code++ = ((bch_val[2] >> 16) & 0xFF); + *ecc_code++ = ((bch_val[2] >> 8) & 0xFF); + *ecc_code++ = (bch_val[2] & 0xFF); + *ecc_code++ = ((bch_val[1] >> 24) & 0xFF); + *ecc_code++ = ((bch_val[1] >> 16) & 0xFF); + *ecc_code++ = ((bch_val[1] >> 8) & 0xFF); + *ecc_code++ = (bch_val[1] & 0xFF); + *ecc_code++ = ((bch_val[0] >> 24) & 0xFF); + *ecc_code++ = ((bch_val[0] >> 16) & 0xFF); + *ecc_code++ = ((bch_val[0] >> 8) & 0xFF); + *ecc_code++ = (bch_val[0] & 0xFF); break; case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: case OMAP_ECC_BCH4_CODE_HW: - bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); - bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); - *ecc_code++ = ((bch_val2 >> 12) & 0xFF); - *ecc_code++ = ((bch_val2 >> 4) & 0xFF); - *ecc_code++ = ((bch_val2 & 0xF) << 4) | - ((bch_val1 >> 28) & 0xF); - *ecc_code++ = ((bch_val1 >> 20) & 0xFF); - *ecc_code++ = ((bch_val1 >> 12) & 0xFF); - *ecc_code++ = ((bch_val1 >> 4) & 0xFF); - *ecc_code++ = ((bch_val1 & 0xF) << 4); + omap_gpmc_ecc_get_bch_result(2, i, bch_val); + *ecc_code++ = ((bch_val[1] >> 12) & 0xFF); + *ecc_code++ = ((bch_val[1] >> 4) & 0xFF); + *ecc_code++ = ((bch_val[1] & 0xF) << 4) | + ((bch_val[0] >> 28) & 0xF); + *ecc_code++ = ((bch_val[0] >> 20) & 0xFF); + *ecc_code++ = ((bch_val[0] >> 12) & 0xFF); + *ecc_code++ = ((bch_val[0] >> 4) & 0xFF); + *ecc_code++ = ((bch_val[0] & 0xF) << 4); break; case OMAP_ECC_BCH16_CODE_HW: - val = readl(gpmc_regs->gpmc_bch_result6[i]); - ecc_code[0] = ((val >> 8) & 0xFF); - ecc_code[1] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result5[i]); - ecc_code[2] = ((val >> 24) & 0xFF); - ecc_code[3] = ((val >> 16) & 0xFF); - ecc_code[4] = ((val >> 8) & 0xFF); - ecc_code[5] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result4[i]); - ecc_code[6] = ((val >> 24) & 0xFF); - ecc_code[7] = ((val >> 16) & 0xFF); - ecc_code[8] = ((val >> 8) & 0xFF); - ecc_code[9] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result3[i]); - ecc_code[10] = ((val >> 24) & 0xFF); - ecc_code[11] = ((val >> 16) & 0xFF); - ecc_code[12] = ((val >> 8) & 0xFF); - ecc_code[13] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result2[i]); - ecc_code[14] = ((val >> 24) & 0xFF); - ecc_code[15] = ((val >> 16) & 0xFF); - ecc_code[16] = ((val >> 8) & 0xFF); - ecc_code[17] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result1[i]); - ecc_code[18] = ((val >> 24) & 0xFF); - ecc_code[19] = ((val >> 16) & 0xFF); - ecc_code[20] = ((val >> 8) & 0xFF); - ecc_code[21] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result0[i]); - ecc_code[22] = ((val >> 24) & 0xFF); - ecc_code[23] = ((val >> 16) & 0xFF); - ecc_code[24] = ((val >> 8) & 0xFF); - ecc_code[25] = ((val >> 0) & 0xFF); + omap_gpmc_ecc_get_bch_result(7, i, bch_val); + ecc_code[0] = ((bch_val[6] >> 8) & 0xFF); + ecc_code[1] = ((bch_val[6] >> 0) & 0xFF); + + ecc_code[2] = ((bch_val[5] >> 24) & 0xFF); + ecc_code[3] = ((bch_val[5] >> 16) & 0xFF); + ecc_code[4] = ((bch_val[5] >> 8) & 0xFF); + ecc_code[5] = ((bch_val[5] >> 0) & 0xFF); + + ecc_code[6] = ((bch_val[4] >> 24) & 0xFF); + ecc_code[7] = ((bch_val[4] >> 16) & 0xFF); + ecc_code[8] = ((bch_val[4] >> 8) & 0xFF); + ecc_code[9] = ((bch_val[4] >> 0) & 0xFF); + + ecc_code[10] = ((bch_val[3] >> 24) & 0xFF); + ecc_code[11] = ((bch_val[3] >> 16) & 0xFF); + ecc_code[12] = ((bch_val[3] >> 8) & 0xFF); + ecc_code[13] = ((bch_val[3] >> 0) & 0xFF); + + ecc_code[14] = ((bch_val[2] >> 24) & 0xFF); + ecc_code[15] = ((bch_val[2] >> 16) & 0xFF); + ecc_code[16] = ((bch_val[2] >> 8) & 0xFF); + ecc_code[17] = ((bch_val[2] >> 0) & 0xFF); + + ecc_code[18] = ((bch_val[1] >> 24) & 0xFF); + ecc_code[19] = ((bch_val[1] >> 16) & 0xFF); + ecc_code[20] = ((bch_val[1] >> 8) & 0xFF); + ecc_code[21] = ((bch_val[1] >> 0) & 0xFF); + + ecc_code[22] = ((bch_val[0] >> 24) & 0xFF); + ecc_code[23] = ((bch_val[0] >> 16) & 0xFF); + ecc_code[24] = ((bch_val[0] >> 8) & 0xFF); + ecc_code[25] = ((bch_val[0] >> 0) & 0xFF); break; default: return -EINVAL;