Skip to content

Commit

Permalink
ARM: pxa: fix DFI bus lockups on startup
Browse files Browse the repository at this point in the history
After the conversion of pxa architecture to common clock framework, the
NAND clock can be disabled on startup if no nand driver claims it.

In this case, it happens that if the bootloader used the NAND and set
the DFI arbitration bit, the next access to a static memory controller
area, such as an ethernet card, the system bus will stall, and the core
will be stalled forever.

Fix this by clearing the DFI arbritration bit in pxa3xx startup. The bit
will be enabled the pxa3xx-nand driver on need anyway. The only left
requirement is that upon pxa3xx-nand removal, the bit should be cleared
before the clock is disabled.

Signed-off-by: Robert Jarzmik <[email protected]>
  • Loading branch information
rjarzmik committed Sep 13, 2015
1 parent 6ff33f3 commit adf3442
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
7 changes: 7 additions & 0 deletions arch/arm/mach-pxa/include/mach/addr-map.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
* 0xf6200000..0xf6201000
*/

/*
* DFI Bus for NAND, PXA3xx only
*/
#define NAND_PHYS 0x43100000
#define NAND_VIRT IOMEM(0xf6300000)
#define NAND_SIZE 0x00100000

/*
* Internal Memory Controller (PXA27x and later)
*/
Expand Down
21 changes: 20 additions & 1 deletion arch/arm/mach-pxa/pxa3xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
#define ISRAM_START 0x5c000000
#define ISRAM_SIZE SZ_256K

/*
* NAND NFC: DFI bus arbitration subset
*/
#define NDCR (*(volatile u32 __iomem*)(NAND_VIRT + 0))
#define NDCR_ND_ARB_EN (1 << 12)
#define NDCR_ND_ARB_CNTL (1 << 19)

static void __iomem *sram;
static unsigned long wakeup_src;

Expand Down Expand Up @@ -362,7 +369,12 @@ static struct map_desc pxa3xx_io_desc[] __initdata = {
.pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE),
.length = SMEMC_SIZE,
.type = MT_DEVICE
}
}, {
.virtual = (unsigned long)NAND_VIRT,
.pfn = __phys_to_pfn(NAND_PHYS),
.length = NAND_SIZE,
.type = MT_DEVICE
},
};

void __init pxa3xx_map_io(void)
Expand Down Expand Up @@ -419,6 +431,13 @@ static int __init pxa3xx_init(void)
*/
ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);

/*
* Disable DFI bus arbitration, to prevent a system bus lock if
* somebody disables the NAND clock (unused clock) while this
* bit remains set.
*/
NDCR = (NDCR & ~NDCR_ND_ARB_EN) | NDCR_ND_ARB_CNTL;

if ((ret = pxa_init_dma(IRQ_DMA, 32)))
return ret;

Expand Down

0 comments on commit adf3442

Please sign in to comment.