Message ID | 1335442669-13474-1-git-send-email-ivan.djelic@parrot.com |
---|---|
State | Not Applicable |
Headers | show |
* Ivan Djelic <ivan.djelic@parrot.com> [120426 05:23]: > Hello, > > Here is version 3 of this patch after review from Tony Lindgren. > This version adds a separate initialization function mostly to check CPU > compatibility. This check cannot be done in gpmc_enable_hwecc_bch() (which > is meant to be called from mtd function ecc.hwctl) because ecc.hwctl is > not called before the first NAND read access, and it cannot return an error > status. Thanks applying into devel-gpmc branch. Tony
On Wed, May 09, 2012 at 01:29:28AM +0100, Tony Lindgren wrote: > * Ivan Djelic <ivan.djelic@parrot.com> [120426 05:23]: > > Hello, > > > > Here is version 3 of this patch after review from Tony Lindgren. > > This version adds a separate initialization function mostly to check CPU > > compatibility. This check cannot be done in gpmc_enable_hwecc_bch() (which > > is meant to be called from mtd function ecc.hwctl) because ecc.hwctl is > > not called before the first NAND read access, and it cannot return an error > > status. > > Thanks applying into devel-gpmc branch. OK thanks! I still have a question though: there are recent patches from Afzal Mohammed that seem to go into the opposite direction, that is giving back GPMC register access to the omap2 NAND driver. In particular, [PATCH v4 17/39] [1] commit message says: GPMC driver has been modified to fill NAND platform data with GPMC NAND register details. As these registers are accessible in NAND driver itself, configure NAND in GPMC by itself. This also includes ecc configuration. My original mtd driver patch indeed had ecc handling code inside the driver (not in arch/arm/mach-omap2/gpmc.c). So, my question is: which direction are we going to with respect to this OMAP GPMC/NAND code separation ? Note that I could prepare a new MTD patch with BCH ecc code included, allowing to drop the GPMC BCH ecc api. BR, -- Ivan [1] http://lists.infradead.org/pipermail/linux-mtd/2012-May/041105.html
On Wed, May 09, 2012 at 01:29:28AM +0100, Tony Lindgren wrote: > * Ivan Djelic <ivan.djelic@parrot.com> [120426 05:23]: > > Hello, > > > > Here is version 3 of this patch after review from Tony Lindgren. > > This version adds a separate initialization function mostly to check CPU > > compatibility. This check cannot be done in gpmc_enable_hwecc_bch() (which > > is meant to be called from mtd function ecc.hwctl) because ecc.hwctl is > > not called before the first NAND read access, and it cannot return an error > > status. > > Thanks applying into devel-gpmc branch. OK thanks! I still have a question though: there are recent patches from Afzal Mohammed that seem to go into the opposite direction, that is giving back GPMC register access to the omap2 NAND driver. In particular, [PATCH v4 17/39] [1] commit message says: GPMC driver has been modified to fill NAND platform data with GPMC NAND register details. As these registers are accessible in NAND driver itself, configure NAND in GPMC by itself. This also includes ecc configuration. My original mtd driver patch indeed had ecc handling code inside the driver (not in arch/arm/mach-omap2/gpmc.c). So, my question is: which direction are we going to with respect to this OMAP GPMC/NAND code separation ? Note that I could prepare a new MTD patch with BCH ecc code included, allowing to drop the GPMC BCH ecc api. BR, -- Ivan [1] http://lists.infradead.org/pipermail/linux-mtd/2012-May/041105.html
* Ivan Djelic <ivan.djelic@parrot.com> [120509 01:15]: > On Wed, May 09, 2012 at 01:29:28AM +0100, Tony Lindgren wrote: > > * Ivan Djelic <ivan.djelic@parrot.com> [120426 05:23]: > > > Hello, > > > > > > Here is version 3 of this patch after review from Tony Lindgren. > > > This version adds a separate initialization function mostly to check CPU > > > compatibility. This check cannot be done in gpmc_enable_hwecc_bch() (which > > > is meant to be called from mtd function ecc.hwctl) because ecc.hwctl is > > > not called before the first NAND read access, and it cannot return an error > > > status. > > > > Thanks applying into devel-gpmc branch. > > OK thanks! > > I still have a question though: there are recent patches from > Afzal Mohammed that seem to go into the opposite direction, that is > giving back GPMC register access to the omap2 NAND driver. > In particular, [PATCH v4 17/39] [1] commit message says: > > GPMC driver has been modified to fill NAND platform data with GPMC > NAND register details. As these registers are accessible in NAND > driver itself, configure NAND in GPMC by itself. > > This also includes ecc configuration. My original mtd driver patch indeed had > ecc handling code inside the driver (not in arch/arm/mach-omap2/gpmc.c). > > So, my question is: which direction are we going to with respect to this > OMAP GPMC/NAND code separation ? What Afzal is doing is where we're heading. However, I'm afraid that may not be quite ready for v3.5 merge window as it needs proper testing on quite a few platforms to avoid issues with various devices connected to GPMC. > Note that I could prepare a new MTD patch with BCH ecc code included, > allowing to drop the GPMC BCH ecc api. OK, let's do that then. I'll drop this patch and you can coordinate your patch with Afzal. Regards, Tony > [1] http://lists.infradead.org/pipermail/linux-mtd/2012-May/041105.html
Hi Ivan, On Wed, May 09, 2012 at 21:01:42, Tony Lindgren wrote: > > Note that I could prepare a new MTD patch with BCH ecc code included, > > allowing to drop the GPMC BCH ecc api. > > OK, let's do that then. I'll drop this patch and you can coordinate > your patch with Afzal. Now that some review comments has been received on the series, let me try to come up with a suitable way forward and contact you within a day or two. Regards Afzal
On Wed, 2012-05-09 at 08:31 -0700, Tony Lindgren wrote: > > Note that I could prepare a new MTD patch with BCH ecc code included, > > allowing to drop the GPMC BCH ecc api. > > OK, let's do that then. I'll drop this patch and you can coordinate > your patch with Afzal. Ivan, so are you going to send new patches early enough to make them hit 3.5? Can you please then re-send all the dependent patches again and again describe what depends on what, because I am getting lost :-)
On Thu, May 10, 2012 at 02:07:37PM +0100, Artem Bityutskiy wrote: > On Wed, 2012-05-09 at 08:31 -0700, Tony Lindgren wrote: > > > Note that I could prepare a new MTD patch with BCH ecc code included, > > > allowing to drop the GPMC BCH ecc api. > > > > OK, let's do that then. I'll drop this patch and you can coordinate > > your patch with Afzal. > > Ivan, so are you going to send new patches early enough to make them hit > 3.5? Can you please then re-send all the dependent patches again and > again describe what depends on what, because I am getting lost :-) Yes, I agree this has become a bit confusing. I currently have 2 pending patches: [1] ARM-OMAP3-gpmc-add-BCH-ecc-api-and-modes_v3.patch (linux-omap) [2] mtd-nand-omap-add-support-for-hardware-BCH-ecc_v2.patch (linux-mtd) They should both be dropped. I will basically merge the two patches and submit a new single patch on MTD only, with no dependency. I won't need to patch arch/arm/mach-omap2 anymore. But in order to do so, I need the changes that Afzal has submitted (in particular [3]). Those changes (and as a consequence, my new patch) won't hit 3.5. So, when Afzal's patches are pushed, I'll submit a new, single MTD patch. BR, -- Ivan [1] http://lists.infradead.org/pipermail/linux-mtd/2012-April/040965.html [2] http://lists.infradead.org/pipermail/linux-mtd/2012-April/041020.html [3] http://lists.infradead.org/pipermail/linux-mtd/2012-May/041105.html
On Thu, 2012-05-10 at 17:17 +0200, Ivan Djelic wrote: > But in order to do so, I need the changes that Afzal has submitted > (in particular [3]). Those changes (and as a consequence, my new patch) > won't hit 3.5. > > So, when Afzal's patches are pushed, I'll submit a new, single MTD patch. But this is not going to happen this merge window as I understood, may be not even the next one. We need to make UBIFS happy sooner than that, I think. So may be we go forward with your original patch?
On Thu, May 10, 2012 at 04:52:18PM +0100, Artem Bityutskiy wrote: > On Thu, 2012-05-10 at 17:17 +0200, Ivan Djelic wrote: > > But in order to do so, I need the changes that Afzal has submitted > > (in particular [3]). Those changes (and as a consequence, my new patch) > > won't hit 3.5. > > > > So, when Afzal's patches are pushed, I'll submit a new, single MTD patch. > > But this is not going to happen this merge window as I understood, may > be not even the next one. We need to make UBIFS happy sooner than that, > I think. So may be we go forward with your original patch? I'm OK with this too, as the patches are ready and tested. The MTD patch is [2], it depends on [1] which has been pushed, then dropped by Tony. Do you need me to repost [2] ? Tony, sorry to backpedal on this: would you re-push patch [1], if indeed Afzal's patches are not going to be merged soon ? In the meantime, I can prepare a patch on top of Afzal's to have a smooth transition w.r.t BCH support. What do you think ? Best Regards, -- Ivan [1] http://lists.infradead.org/pipermail/linux-mtd/2012-April/040965.html [2] http://lists.infradead.org/pipermail/linux-mtd/2012-April/041020.html
* Ivan Djelic <ivan.djelic@parrot.com> [120510 10:49]: > On Thu, May 10, 2012 at 04:52:18PM +0100, Artem Bityutskiy wrote: > > On Thu, 2012-05-10 at 17:17 +0200, Ivan Djelic wrote: > > > But in order to do so, I need the changes that Afzal has submitted > > > (in particular [3]). Those changes (and as a consequence, my new patch) > > > won't hit 3.5. > > > > > > So, when Afzal's patches are pushed, I'll submit a new, single MTD patch. > > > > But this is not going to happen this merge window as I understood, may > > be not even the next one. We need to make UBIFS happy sooner than that, > > I think. So may be we go forward with your original patch? > > I'm OK with this too, as the patches are ready and tested. > The MTD patch is [2], it depends on [1] which has been pushed, then dropped by Tony. > Do you need me to repost [2] ? > > Tony, sorry to backpedal on this: would you re-push patch [1], if indeed Afzal's patches > are not going to be merged soon ? In the meantime, I can prepare a patch on top of Afzal's to > have a smooth transition w.r.t BCH support. What do you think ? Yes this is OK with me as this removes the blocker for UBIFS work. For arch/arm/mach-omap2/gpmc.c, I have the following two patches queued: 27aeb3da5f97c55f61d92e3dbfb738762f76dc32 Merge tag 'omap-cleanup-for-v3.5' into tmp-merge 2c65e7440d56b3b285d1c95563b4dcce8e40dea3 GPMC: add ECC control definitions 355f8eee48134ba10ca81664ee90eeb240f5f928 ARM: OMAP2+: GPMC: resolve type-conversion warning from sparse Looks your patch applies to v3.4-rc6 and what I have queued without conflicts, so I suggest you merge both via MTD patches: Acked-by: Tony Lindgren <tony@atomide.com> > [1] http://lists.infradead.org/pipermail/linux-mtd/2012-April/040965.html > [2] http://lists.infradead.org/pipermail/linux-mtd/2012-April/041020.html
On Thu, 2012-05-10 at 19:45 +0200, Ivan Djelic wrote: > On Thu, May 10, 2012 at 04:52:18PM +0100, Artem Bityutskiy wrote: > > On Thu, 2012-05-10 at 17:17 +0200, Ivan Djelic wrote: > > > But in order to do so, I need the changes that Afzal has submitted > > > (in particular [3]). Those changes (and as a consequence, my new patch) > > > won't hit 3.5. > > > > > > So, when Afzal's patches are pushed, I'll submit a new, single MTD patch. > > > > But this is not going to happen this merge window as I understood, may > > be not even the next one. We need to make UBIFS happy sooner than that, > > I think. So may be we go forward with your original patch? > > I'm OK with this too, as the patches are ready and tested. > The MTD patch is [2], it depends on [1] which has been pushed, then dropped by Tony. > Do you need me to repost [2] ? > > Tony, sorry to backpedal on this: would you re-push patch [1], if indeed Afzal's patches > are not going to be merged soon ? In the meantime, I can prepare a patch on top of Afzal's to > have a smooth transition w.r.t BCH support. What do you think ? OK, since we now have Tony's ack - I have applied both patches to l2-mtd.git. Thanks. I have a question though - will send separately.
Hi Ivan, On Thu, May 10, 2012 at 23:15:27, Ivan Djelic wrote: > > > So, when Afzal's patches are pushed, I'll submit a new, single MTD patch. > > > > But this is not going to happen this merge window as I understood, may > > be not even the next one. We need to make UBIFS happy sooner than that, > > I think. So may be we go forward with your original patch? > > I'm OK with this too, as the patches are ready and tested. > The MTD patch is [2], it depends on [1] which has been pushed, then dropped by Tony. > Do you need me to repost [2] ? > > Tony, sorry to backpedal on this: would you re-push patch [1], if indeed Afzal's patches > are not going to be merged soon ? In the meantime, I can prepare a patch on top of Afzal's to > have a smooth transition w.r.t BCH support. What do you think ? A new series [A-D] has been sent for handling GPMC NAND registers by NAND driver itself. This is being targeted for 3.5. Hopefully if every one is in agreement, we can avoid patching for BCH support again when GPMC driver migration happens. And the effect of GPMC driver migration on NAND driver can be reduced when it happens. Can you try a patch on top of this series & checks if it works for you, if more is required from my side let me know. Regards Afzal [A] http://marc.info/?l=linux-omap&m=133675113218509&w=2 [B] http://marc.info/?l=linux-omap&m=133675123118577&w=2 [C] http://marc.info/?l=linux-omap&m=133675123718579&w=2 [D] http://marc.info/?l=linux-omap&m=133675124818580&w=2
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 00d5108..1ca8d7f 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -49,6 +49,7 @@ #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc #define GPMC_ECC1_RESULT 0x200 +#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */ #define GPMC_CS0_OFFSET 0x60 #define GPMC_CS_SIZE 0x30 @@ -920,3 +921,186 @@ int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code) return 0; } EXPORT_SYMBOL_GPL(gpmc_calculate_ecc); + +#ifdef CONFIG_ARCH_OMAP3 + +/** + * gpmc_init_hwecc_bch - initialize hardware BCH ecc functionality + * @cs: chip select number + * @nsectors: how many 512-byte sectors to process + * @nerrors: how many errors to correct per sector (4 or 8) + * + * This function must be executed before any call to gpmc_enable_hwecc_bch. + */ +int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors) +{ + /* check if ecc module is in use */ + if (gpmc_ecc_used != -EINVAL) + return -EINVAL; + + /* support only OMAP3 class */ + if (!cpu_is_omap34xx()) { + printk(KERN_ERR "BCH ecc is not supported on this CPU\n"); + return -EINVAL; + } + + /* + * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1. + * Other chips may be added if confirmed to work. + */ + if ((nerrors == 4) && + (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) { + printk(KERN_ERR "BCH 4-bit mode is not supported on this CPU\n"); + return -EINVAL; + } + + /* sanity check */ + if (nsectors > 8) { + printk(KERN_ERR "BCH cannot process %d sectors (max is 8)\n", + nsectors); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(gpmc_init_hwecc_bch); + +/** + * gpmc_enable_hwecc_bch - enable hardware BCH ecc functionality + * @cs: chip select number + * @mode: read/write mode + * @dev_width: device bus width(1 for x16, 0 for x8) + * @nsectors: how many 512-byte sectors to process + * @nerrors: how many errors to correct per sector (4 or 8) + */ +int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors, + int nerrors) +{ + unsigned int val; + + /* check if ecc module is in use */ + if (gpmc_ecc_used != -EINVAL) + return -EINVAL; + + gpmc_ecc_used = cs; + + /* clear ecc and enable bits */ + gpmc_write_reg(GPMC_ECC_CONTROL, 0x1); + + /* + * When using BCH, sector size is hardcoded to 512 bytes. + * Here we are using wrapping mode 6 both for reading and writing, with: + * size0 = 0 (no additional protected byte in spare area) + * size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area) + */ + gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, (32 << 22) | (0 << 12)); + + /* BCH configuration */ + val = ((1 << 16) | /* enable BCH */ + (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */ + (0x06 << 8) | /* wrap mode = 6 */ + (dev_width << 7) | /* bus width */ + (((nsectors-1) & 0x7) << 4) | /* number of sectors */ + (cs << 1) | /* ECC CS */ + (0x1)); /* enable ECC */ + + gpmc_write_reg(GPMC_ECC_CONFIG, val); + gpmc_write_reg(GPMC_ECC_CONTROL, 0x101); + return 0; +} +EXPORT_SYMBOL_GPL(gpmc_enable_hwecc_bch); + +/** + * gpmc_calculate_ecc_bch4 - Generate 7 ecc bytes per sector of 512 data bytes + * @cs: chip select number + * @dat: The pointer to data on which ecc is computed + * @ecc: The ecc output buffer + */ +int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc) +{ + int i; + unsigned long nsectors, reg, val1, val2; + + if (gpmc_ecc_used != cs) + return -EINVAL; + + nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1; + + for (i = 0; i < nsectors; i++) { + + reg = GPMC_ECC_BCH_RESULT_0 + 16*i; + + /* Read hw-computed remainder */ + val1 = gpmc_read_reg(reg + 0); + val2 = gpmc_read_reg(reg + 4); + + /* + * Add constant polynomial to remainder, in order to get an ecc + * sequence of 0xFFs for a buffer filled with 0xFFs; and + * left-justify the resulting polynomial. + */ + *ecc++ = 0x28 ^ ((val2 >> 12) & 0xFF); + *ecc++ = 0x13 ^ ((val2 >> 4) & 0xFF); + *ecc++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF)); + *ecc++ = 0x39 ^ ((val1 >> 20) & 0xFF); + *ecc++ = 0x96 ^ ((val1 >> 12) & 0xFF); + *ecc++ = 0xac ^ ((val1 >> 4) & 0xFF); + *ecc++ = 0x7f ^ ((val1 & 0xF) << 4); + } + + gpmc_ecc_used = -EINVAL; + return 0; +} +EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch4); + +/** + * gpmc_calculate_ecc_bch8 - Generate 13 ecc bytes per block of 512 data bytes + * @cs: chip select number + * @dat: The pointer to data on which ecc is computed + * @ecc: The ecc output buffer + */ +int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc) +{ + int i; + unsigned long nsectors, reg, val1, val2, val3, val4; + + if (gpmc_ecc_used != cs) + return -EINVAL; + + nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1; + + for (i = 0; i < nsectors; i++) { + + reg = GPMC_ECC_BCH_RESULT_0 + 16*i; + + /* Read hw-computed remainder */ + val1 = gpmc_read_reg(reg + 0); + val2 = gpmc_read_reg(reg + 4); + val3 = gpmc_read_reg(reg + 8); + val4 = gpmc_read_reg(reg + 12); + + /* + * Add constant polynomial to remainder, in order to get an ecc + * sequence of 0xFFs for a buffer filled with 0xFFs. + */ + *ecc++ = 0xef ^ (val4 & 0xFF); + *ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF); + *ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF); + *ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF); + *ecc++ = 0xed ^ (val3 & 0xFF); + *ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF); + *ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF); + *ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF); + *ecc++ = 0x97 ^ (val2 & 0xFF); + *ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF); + *ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF); + *ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF); + *ecc++ = 0xb5 ^ (val1 & 0xFF); + } + + gpmc_ecc_used = -EINVAL; + return 0; +} +EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch8); + +#endif /* CONFIG_ARCH_OMAP3 */ diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 1527929..f37764a 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -92,6 +92,8 @@ enum omap_ecc { OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ /* 1-bit ecc: stored at beginning of spare area as romcode */ OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ + OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */ + OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */ }; /* @@ -157,4 +159,13 @@ extern int gpmc_nand_write(int cs, int cmd, int wval); int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size); int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code); + +#ifdef CONFIG_ARCH_OMAP3 +int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors); +int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors, + int nerrors); +int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc); +int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc); +#endif /* CONFIG_ARCH_OMAP3 */ + #endif
Hello, Here is version 3 of this patch after review from Tony Lindgren. This version adds a separate initialization function mostly to check CPU compatibility. This check cannot be done in gpmc_enable_hwecc_bch() (which is meant to be called from mtd function ecc.hwctl) because ecc.hwctl is not called before the first NAND read access, and it cannot return an error status. -- Ivan This patch adds a simple BCH ecc computation api, similar to the existing Hamming ecc api. It is intended to be used by the MTD layer. It implements the following features: - support 4-bit and 8-bit ecc computation - do not protect user bytes in spare area, only data area is protected - ecc for an erased NAND page (0xFFs) is also a sequence of 0xFFs This last feature is obtained by adding a constant polynomial to the hardware computed ecc. It allows to correct bitflips in blank pages and is extremely useful to support filesystems such as UBIFS, which expect erased pages to contain only 0xFFs. This api has been tested on an OMAP3630 board. Signed-off-by: Ivan Djelic <ivan.djelic@parrot.com> --- v3 changelog: added init function to check CPU compatibility v2 changelog: added missing control register configuration arch/arm/mach-omap2/gpmc.c | 184 ++++++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/gpmc.h | 11 ++ 2 files changed, 195 insertions(+)