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