It was originally posted at
http://sourceforge.net/projects/hh2b4ever/files/

The file is 904-MIPS-lantiq-nand.patch in

http://sourceforge.net/projects/hh2b4ever/files/Patches-20120414.zip

There is also a compilation of bits and pieces from the original
factory firmware, including the nand driver, in

http://sourceforge.net/projects/hh2b4ever/files/Original%20Open%
20Source/

Ben

On Wed, 2014-01-22 at 00:43 +0100, John Crispin wrote:
> Hi,
> 
> i am pretty sure the pinmux is set correctly on the board, however i
> will reverify it.
> 
> do you have a link to btsimonh's 3.3.8 patch ?
> 
>     John
> 
> 
> On 21/01/2014 23:52, Ben Mulvihill wrote:
> > Hi John,
> >
> > Thank you. I had assumed this would probably only be of any use
> > on the HH2B. If you are going to try it (or bits of it) out on
> > the fritz3370, I should perhaps add that BTSimonh's patch for
> > the 3.3.8 kernel (I take it he didn't ever submit it here?)
> > also reset the chip in the chip select function (at the
> > end of case 0) and masked out NANDM at the end of the probe
> > function. I removed those changes because they didn't seem to
> > make any difference. 
> > But could the errors on the fritz3370 simply be due to wrong
> > pinmux settings?
> >
> > Ben
> >
> >
> >
> >
> >
> > On Tue, 2014-01-21 at 21:43 +0100, John Crispin wrote:
> >> Hi Ben,
> >>
> >> oh dear, how i hate the ebu ...
> >>
> >> i will start by testing this patch on the fritz3370 where i have been
> >> seeing jffs2 errors.
> >>
> >> in general i am all for merging this, i will need a few days to think
> >> about this.
> >>
> >>     John
> >>
> >> On 21/01/2014 20:50, Ben Mulvihill wrote:
> >>> Together with other contributors at the now defunct psidoc site, I
> >>> have produced a device tree and some patches to get the BT Home Hub 2B
> >>> (Lantiq Danube-S) working with recent trunk builds. More work is needed
> >>> before they are ready for submitting, but before going any further, I'd
> >>> be very grateful for some advice from John Crispin or anyone else who
> >>> wants to chip in.
> >>>
> >>> The Home Hub 2B has both nand and nor flash connected to the ebu, plus 
> >>> an ath9k pci wireless card, and the main difficulty is getting all three
> >>> working at the same time without interfering with each other. The nand 
> >>> driver currently in trunk works fine, provided that open-drain is 
> >>> enabled on the ebu cs1 pin, and provided that wireless is off. However, 
> >>> the only way to get the nor chip to work reliably seems to be disable 
> >>> open-drain on ebu cs1, at which point the nand driver generates jffs2 
> >>> errors. Regardless whether open-drain is enabled or not, switching on 
> >>> wireless also causes jffs2 errors.
> >>>
> >>> The solution we are using (basically an updated version of a patch 
> >>> produced by BTSimonh for the 3.3.8 kernel) is to disable open drain on 
> >>> ebu cs1 and patch the nand driver as follows:
> >>>  - move locking from the individual read and write functions to the
> >>>    chip select function, so that an entire read or write operation can
> >>>    complete uninterrupted;
> >>>  - mask pci request lines during nand access;
> >>>  - additional waiting after each nand command.
> >>> An option in the device tree enables or disables the above.
> >>> The latest version of my patch is appended to the message, for comment 
> >>> only - I am not submitting it at this stage.
> >>>
> >>> It solves the problem, and the factory firmware does something similar,
> >>> but it feels like a hack to work round a bug elsewhere. Could it not be
> >>> that that the ebu needs to be set up differently for this hardware
> >>> configuration? Is some chip select logic needed in the nor driver?
> >>> I'd love to understand what the settings in the ebu registers actually
> >>> do, but am I right in thinking that there are no publicly available
> >>> datasheets for Lantiq SOCs?
> >>>
> >>> Any enlightenment you can provide will be gratefully received.
> >>>
> >>> Thank you,
> >>>
> >>> Ben Mulvihill
> >>>
> >>> --- a/drivers/mtd/nand/xway_nand.c        2014-01-21 20:21:11.000000000 
> >>> +0100
> >>> +++ b/drivers/mtd/nand/xway_nand.c        2014-01-21 20:29:16.000000000 
> >>> +0100
> >>> @@ -54,8 +54,28 @@
> >>>  #define NAND_CON_CSMUX           (1 << 1)
> >>>  #define NAND_CON_NANDM           1
> >>>  
> >>> +#define DANUBE_PCI_REG32( addr )    (*(volatile u32 *)(addr))
> >>> +#define PCI_CR_PR_OFFSET     (KSEG1+0x1E105400)
> >>> +#define PCI_CR_PC_ARB                (PCI_CR_PR_OFFSET + 0x0080)
> >>> +
> >>>  static u32 xway_latchcmd;
> >>>  
> >>> +/*
> >>> + * req_mask provides a mechanism to prevent interference between
> >>> + * nand and pci (probably only relevant for the BT Home Hub 2B).
> >>> + * Setting it causes the corresponding pci req pins to be masked
> >>> + * during nand access, and also moves ebu locking from the read/write
> >>> + * functions to the chip select function to ensure that the whole
> >>> + * operation runs with interrupts disabled.
> >>> + * In addition it switches on some extra waiting in xway_cmd_ctrl().
> >>> + * This seems to be necessary if the ebu_cs1 pin has open-drain disabled,
> >>> + * which in turn seems to be necessary for the nor chip to be recognised
> >>> + * reliably, on a board (Home Hub 2B again) which has both nor and nand.
> >>> + */
> >>> +
> >>> +static __be32 req_mask = 0;
> >>> +static int pci_masked = 0;
> >>> +
> >>>  static void xway_reset_chip(struct nand_chip *chip)
> >>>  {
> >>>   unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
> >>> @@ -80,15 +100,36 @@
> >>>  
> >>>  static void xway_select_chip(struct mtd_info *mtd, int chip)
> >>>  {
> >>> + static unsigned long flags;
> >>>  
> >>>   switch (chip) {
> >>>   case -1:
> >>>           ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
> >>>           ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
> >>> +
> >>> +         if (req_mask) {
> >>> +                 BUG_ON(!pci_masked);
> >>> +                 /* Unmask all external PCI request */
> >>> +                 DANUBE_PCI_REG32(PCI_CR_PC_ARB) &= ~(req_mask << 16);
> >>> +                 pci_masked = 0;
> >>> +
> >>> +                 spin_unlock_irqrestore(&ebu_lock, flags);
> >>> +         }
> >>> +
> >>>           break;
> >>>   case 0:
> >>> +         if (req_mask) {
> >>> +                 BUG_ON(pci_masked);
> >>> +                 spin_lock_irqsave(&ebu_lock, flags);
> >>> +
> >>> +                 /* Mask all external PCI request */
> >>> +                 DANUBE_PCI_REG32(PCI_CR_PC_ARB) |= (req_mask << 16);
> >>> +                 pci_masked = 1;
> >>> +         }
> >>> +
> >>>           ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
> >>>           ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
> >>> +
> >>>           break;
> >>>   default:
> >>>           BUG();
> >>> @@ -101,6 +142,12 @@
> >>>   unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
> >>>   unsigned long flags;
> >>>  
> >>> + if (req_mask) {
> >>> +         if (cmd != NAND_CMD_STATUS)
> >>> +                 ltq_ebu_w32(EBU_NAND_WAIT, 0); /* Clear nand ready */
> >>> + }
> >>> +
> >>> +
> >>>   if (ctrl & NAND_CTRL_CHANGE) {
> >>>           if (ctrl & NAND_CLE)
> >>>                   xway_latchcmd = NAND_WRITE_CMD;
> >>> @@ -109,11 +156,31 @@
> >>>   }
> >>>  
> >>>   if (cmd != NAND_CMD_NONE) {
> >>> -         spin_lock_irqsave(&ebu_lock, flags);
> >>> +         if (!req_mask)
> >>> +                 spin_lock_irqsave(&ebu_lock, flags);
> >>>           writeb(cmd, (void __iomem *) (nandaddr | xway_latchcmd));
> >>>           while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
> >>>                   ;
> >>> -         spin_unlock_irqrestore(&ebu_lock, flags);
> >>> +         if (!req_mask)
> >>> +                 spin_unlock_irqrestore(&ebu_lock, flags);
> >>> + }
> >>> +
> >>> + if (req_mask) {
> >>> +        /*
> >>> +         * program and erase have their own busy handlers
> >>> +         * status and sequential in needs no delay
> >>> +         */
> >>> +         switch (cmd) {
> >>> +                 case NAND_CMD_ERASE1:
> >>> +                 case NAND_CMD_SEQIN:
> >>> +                 case NAND_CMD_STATUS:
> >>> +                 case NAND_CMD_READID:
> >>> +                 return;
> >>> +         }
> >>> +
> >>> +         /* wait until command is processed */
> >>> +         while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
> >>> +                 ;
> >>>   }
> >>>  }
> >>>  
> >>> @@ -129,9 +196,11 @@
> >>>   unsigned long flags;
> >>>   int ret;
> >>>  
> >>> - spin_lock_irqsave(&ebu_lock, flags);
> >>> + if (!req_mask)
> >>> +         spin_lock_irqsave(&ebu_lock, flags);
> >>>   ret = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
> >>> - spin_unlock_irqrestore(&ebu_lock, flags);
> >>> + if (!req_mask)
> >>> +         spin_unlock_irqrestore(&ebu_lock, flags);
> >>>  
> >>>   return ret;
> >>>  }
> >>> @@ -143,10 +212,12 @@
> >>>   unsigned long flags;
> >>>   int i;
> >>>  
> >>> - spin_lock_irqsave(&ebu_lock, flags);
> >>> + if (!req_mask)
> >>> +         spin_lock_irqsave(&ebu_lock, flags);
> >>>   for (i = 0; i < len; i++)
> >>>           buf[i] = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
> >>> - spin_unlock_irqrestore(&ebu_lock, flags);
> >>> + if (!req_mask)
> >>> +         spin_unlock_irqrestore(&ebu_lock, flags);
> >>>  }
> >>>  
> >>>  static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int 
> >>> len)
> >>> @@ -156,16 +227,20 @@
> >>>   unsigned long flags;
> >>>   int i;
> >>>  
> >>> - spin_lock_irqsave(&ebu_lock, flags);
> >>> + if (!req_mask)
> >>> +         spin_lock_irqsave(&ebu_lock, flags);
> >>>   for (i = 0; i < len; i++)
> >>>           ltq_w8(buf[i], (void __iomem *)nandaddr);
> >>> - spin_unlock_irqrestore(&ebu_lock, flags);
> >>> + if (!req_mask)
> >>> +         spin_unlock_irqrestore(&ebu_lock, flags);
> >>>  }
> >>>  
> >>>  static int xway_nand_probe(struct platform_device *pdev)
> >>>  {
> >>>   struct nand_chip *this = platform_get_drvdata(pdev);
> >>>   unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
> >>> + const __be32 *req_mask_ptr = of_get_property(pdev->dev.of_node,
> >>> +                                 "req-mask", NULL);
> >>>   const __be32 *cs = of_get_property(pdev->dev.of_node,
> >>>                                   "lantiq,cs", NULL);
> >>>   u32 cs_flag = 0;
> >>> @@ -174,6 +249,8 @@
> >>>   if (cs && (*cs == 1))
> >>>           cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
> >>>  
> >>> + req_mask = (req_mask_ptr ? *req_mask_ptr : 0);
> >>> +
> >>>   /* setup the EBU to run in NAND mode on our base addr */
> >>>   ltq_ebu_w32(CPHYSADDR(nandaddr)
> >>>           | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
> >>> _______________________________________________
> >>> openwrt-devel mailing list
> >>> openwrt-devel@lists.openwrt.org
> >>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
> >>>
> >> _______________________________________________
> >> openwrt-devel mailing list
> >> openwrt-devel@lists.openwrt.org
> >> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
> > _______________________________________________
> > openwrt-devel mailing list
> > openwrt-devel@lists.openwrt.org
> > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
> >
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to