[U-Boot] [PATCH 7/8] mtd: nand: add driver for diskonchip g4 nand flash

2013-04-07 Thread Mike Dunn
This patch adds a driver for the diskonchip G4 nand flash device.  It is based
on the driver from the linux kernel.

This also includes a separate SPL driver.  A separate SPL driver is used because
the device operates in a different mode (reliable mode) when loading a boot
image, and also because the storage format of the boot image is different from
normal data (pages are stored redundantly).  The SPL driver basically mimics how
a typical IPL reads data from the device.  The special operating mode and
storage format are used to compensate for the fact that the IPL does not contain
the BCH ecc decoding algorithm (due to size constraints).  Although the u-boot
SPL *could* use ecc, it operates like an IPL for the sake of simplicity and
uniformity, since the IPL and SPL share the task of loading the u-boot image.
As a side benefit, the SPL driver is very small.

Signed-off-by: Mike Dunn 
---
 drivers/mtd/nand/Makefile|2 +
 drivers/mtd/nand/docg4.c | 1053 ++
 drivers/mtd/nand/docg4_spl.c |  234 ++
 include/linux/mtd/docg4.h|  126 +
 4 files changed, 1415 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/docg4.c
 create mode 100644 drivers/mtd/nand/docg4_spl.c
 create mode 100644 include/linux/mtd/docg4.h

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index c77c0c4..1bcf43c 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -34,6 +34,7 @@ NORMAL_DRIVERS=y
 endif
 
 COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
+COBJS-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
 COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
 COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
 COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
@@ -78,6 +79,7 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
+COBJS-$(CONFIG_NAND_DOCG4) += docg4.o
 
 else  # minimal SPL drivers
 
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
new file mode 100644
index 000..988aa16
--- /dev/null
+++ b/drivers/mtd/nand/docg4.c
@@ -0,0 +1,1053 @@
+/*
+ * drivers/mtd/nand/docg4.c
+ *
+ *  Copyright (C) 2013 Mike Dunn 
+ *
+ * mtd nand driver for M-Systems DiskOnChip G4
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Tested on the Palm Treo 680.  The G4 is also present on Toshiba Portege, 
Asus
+ * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe 
others.
+ * Should work on these as well.  Let me know!
+ *
+ * TODO:
+ *
+ *  Mechanism for management of password-protected areas
+ *
+ *  Hamming ecc when reading oob only
+ *
+ *  According to the M-Sys documentation, this device is also available in a
+ *  "dual-die" configuration having a 256MB capacity, but no mechanism for
+ *  detecting this variant is documented.  Currently this driver assumes 128MB
+ *  capacity.
+ *
+ *  Support for multiple cascaded devices ("floors").  Not sure which gadgets
+ *  contain multiple G4s in a cascaded configuration, if any.
+ *
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * The device has a nop register which M-Sys claims is for the purpose of
+ * inserting precise delays.  But beware; at least some operations fail if the
+ * nop writes are replaced with a generic delay!
+ */
+static inline void write_nop(void __iomem *docptr)
+{
+   writew(0, docptr + DOC_NOP);
+}
+
+
+static int poll_status(void __iomem *docptr)
+{
+   /*
+* Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
+* register.  Operations known to take a long time (e.g., block erase)
+* should sleep for a while before calling this.
+*/
+
+   uint8_t flash_status;
+
+   /* hardware quirk requires reading twice initially */
+   flash_status = readb(docptr + DOC_FLASHCONTROL);
+
+   do {
+   flash_status = readb(docptr + DOC_FLASHCONTROL);
+   } while (!(flash_status & DOC_CTRL_FLASHREADY));
+
+   return 0;
+}
+
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr)
+{
+   /* write the four address bytes packed in docg4_addr to the device */
+
+   writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+   docg4_addr >>= 8;
+   writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+   docg4_addr >>= 8;
+   writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+   docg4_addr >>= 8;
+   writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+}
+
+
+#ifdef DEBUG_DOCG4
+#define dbg(format, arg...) printf("DEBUG: " format, ##arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+
+/*
+ * This is a 

Re: [U-Boot] [PATCH 7/8] mtd: nand: add driver for diskonchip g4 nand flash

2013-04-07 Thread Marek Vasut
Dear Mike Dunn,

> This patch adds a driver for the diskonchip G4 nand flash device.  It is
> based on the driver from the linux kernel.
> 
> This also includes a separate SPL driver.  A separate SPL driver is used
> because the device operates in a different mode (reliable mode) when
> loading a boot image, and also because the storage format of the boot
> image is different from normal data (pages are stored redundantly).  The
> SPL driver basically mimics how a typical IPL reads data from the device. 
> The special operating mode and storage format are used to compensate for
> the fact that the IPL does not contain the BCH ecc decoding algorithm (due
> to size constraints).  Although the u-boot SPL *could* use ecc, it
> operates like an IPL for the sake of simplicity and uniformity, since the
> IPL and SPL share the task of loading the u-boot image. As a side benefit,
> the SPL driver is very small.
> 
> Signed-off-by: Mike Dunn 

Try #ifdef U_BOOT instead of #if 0, no?

Best regards,
Marek Vasut
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 7/8] mtd: nand: add driver for diskonchip g4 nand flash

2013-04-08 Thread Mike Dunn
On 04/07/2013 11:25 PM, Marek Vasut wrote:
[..]
> Try #ifdef U_BOOT instead of #if 0, no?


Marek, can you clarify?  Do you mean something like...

#define U_BOOT
...
#ifndef U_BOOT  /* Currently u-boot does not have for_each_set_bit */
unsigned long bits = ~buf[i];
for_each_set_bit(bitnum, &bits, 8) {
...
#else
uint8_t mask;
for(bitnum = 0, mask = 0x80; bitnum < 8; bitnum++, mask >>= 1) {
if (!(buf[i] & mask)) {

...
#endif

Thanks again,
Mike
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 7/8] mtd: nand: add driver for diskonchip g4 nand flash

2013-04-08 Thread Marek Vasut
Dear Mike Dunn,

> On 04/07/2013 11:25 PM, Marek Vasut wrote:
> [..]
> 
> > Try #ifdef U_BOOT instead of #if 0, no?
> 
> Marek, can you clarify?  Do you mean something like...
> 
> #define U_BOOT
> ...
> #ifndef U_BOOT  /* Currently u-boot does not have for_each_set_bit */
>   unsigned long bits = ~buf[i];
>   for_each_set_bit(bitnum, &bits, 8) {
>   ...
> #else
>   uint8_t mask;
>   for(bitnum = 0, mask = 0x80; bitnum < 8; bitnum++, mask >>= 1) {
>   if (!(buf[i] & mask)) {
> 
>   ...
> #endif

Hrm, I always thought we had some __UBOOT__ defined, but apparently not :-(

Best regards,
Marek Vasut
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 7/8] mtd: nand: add driver for diskonchip g4 nand flash

2013-04-08 Thread Scott Wood

On 04/08/2013 01:25:01 AM, Marek Vasut wrote:

Dear Mike Dunn,

> This patch adds a driver for the diskonchip G4 nand flash device.   
It is

> based on the driver from the linux kernel.
>
> This also includes a separate SPL driver.  A separate SPL driver is  
used

> because the device operates in a different mode (reliable mode) when
> loading a boot image, and also because the storage format of the  
boot
> image is different from normal data (pages are stored  
redundantly).  The
> SPL driver basically mimics how a typical IPL reads data from the  
device.
> The special operating mode and storage format are used to  
compensate for
> the fact that the IPL does not contain the BCH ecc decoding  
algorithm (due

> to size constraints).  Although the u-boot SPL *could* use ecc, it
> operates like an IPL for the sake of simplicity and uniformity,  
since the
> IPL and SPL share the task of loading the u-boot image. As a side  
benefit,

> the SPL driver is very small.
>
> Signed-off-by: Mike Dunn 

Try #ifdef U_BOOT instead of #if 0, no?


Just remove the code that would be hidden by #if 0.  Besides making the  
U-Boot code easier to read, we *want* to get a conflict marker if we  
try to merge in a new upstream version, and those lines were changed in  
Linux.  This would give us an opportunity to see if similar changes are  
needed to the U-Boot version of the code.


Another option would be to introduce for_each_set_bit in U-Boot.

-Scott
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 7/8] mtd: nand: add driver for diskonchip g4 nand flash

2013-04-09 Thread Mike Dunn
On 04/08/2013 05:59 PM, Scott Wood wrote:
> On 04/08/2013 01:25:01 AM, Marek Vasut wrote:
>> Dear Mike Dunn,
>>
>> > This patch adds a driver for the diskonchip G4 nand flash device.  It is
>> > based on the driver from the linux kernel.
>> >
>> > This also includes a separate SPL driver.  A separate SPL driver is used
>> > because the device operates in a different mode (reliable mode) when
>> > loading a boot image, and also because the storage format of the boot
>> > image is different from normal data (pages are stored redundantly).  The
>> > SPL driver basically mimics how a typical IPL reads data from the device.
>> > The special operating mode and storage format are used to compensate for
>> > the fact that the IPL does not contain the BCH ecc decoding algorithm (due
>> > to size constraints).  Although the u-boot SPL *could* use ecc, it
>> > operates like an IPL for the sake of simplicity and uniformity, since the
>> > IPL and SPL share the task of loading the u-boot image. As a side benefit,
>> > the SPL driver is very small.
>> >
>> > Signed-off-by: Mike Dunn 
>>
>> Try #ifdef U_BOOT instead of #if 0, no?
> 
> Just remove the code that would be hidden by #if 0.  Besides making the U-Boot
> code easier to read, we *want* to get a conflict marker if we try to merge in 
> a
> new upstream version, and those lines were changed in Linux.  This would give 
> us
> an opportunity to see if similar changes are needed to the U-Boot version of 
> the
> code.


OK.


> 
> Another option would be to introduce for_each_set_bit in U-Boot.


This was my first inclination, but it looked like a lot of work across multiple
architectures, so I let it go.

Thanks,
Mike
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot