Skip to contentSkip to conversation

Enable PXAFB for PXA27X and PXA3XX

PATCH New Marek Vasut 2 participants 8 messages Jul 6, 2010 – Jul 12, 2010

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/5 Enable PXAFB for PXA27X and PXA3XX

---
 arch/arm/cpu/pxa/pxafb.c |    9 ++++++++-
 common/lcd.c             |   12 ++++++------
 include/lcd.h            |    2 +-
 3 files changed, 15 insertions(+), 8 deletions(-)
arch/arm/cpu/pxa/pxafb.c +8 -1
index d56c5f0..1cb78f0 100644
@@ -292,7 +292,9 @@ static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid)
 
 	return 0;
 }
-
+#ifdef	CONFIG_CPU_MONAHANS
+static inline void pxafb_setup_gpio (vidinfo_t *vid) {}
+#else
 static void pxafb_setup_gpio (vidinfo_t *vid)
 {
 	u_long lccr0;
@@ -349,6 +351,7 @@ static void pxafb_setup_gpio (vidinfo_t *vid)
 		printf("pxafb_setup_gpio: unable to determine bits per pixel\n");
 	}
 }
+#endif
 
 static void pxafb_enable_controller (vidinfo_t *vid)
 {
@@ -363,7 +366,11 @@ static void pxafb_enable_controller (vidinfo_t *vid)
 	FDADR1 = vid->pxa.fdadr1;
 	LCCR0 |= LCCR0_ENB;
 
+#ifdef	CONFIG_CPU_MONAHANS
+	CKENA |= CKENA_1_LCD;
+#else
 	CKEN |= CKEN16_LCD;
+#endif
 
 	debug("FDADR0 = 0x%08x\n", (unsigned int)FDADR0);
 	debug("FDADR1 = 0x%08x\n", (unsigned int)FDADR1);
common/lcd.c +6 -6
index 93ddedf..d854c21 100644
@@ -41,7 +41,7 @@
 #include <lcd.h>
 #include <watchdog.h>
 
-#if defined(CONFIG_PXA250)
+#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS
 #include <asm/byteorder.h>
 #endif
 
@@ -503,7 +503,7 @@ void bitmap_plot (int x, int y)
 	uchar *bmap;
 	uchar *fb;
 	ushort *fb16;
-#if defined(CONFIG_PXA250)
+#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS
 	struct pxafb_info *fbi = &panel_info.pxa;
 #elif defined(CONFIG_MPC823)
 	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
@@ -519,7 +519,7 @@ void bitmap_plot (int x, int y)
 
 	if (NBITS(panel_info.vl_bpix) < 12) {
 		/* Leave room for default color map */
-#if defined(CONFIG_PXA250)
+#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS
 		cmap = (ushort *)fbi->palette;
 #elif defined(CONFIG_MPC823)
 		cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
@@ -615,7 +615,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 	unsigned long pwidth = panel_info.vl_col;
 	unsigned colors, bpix, bmp_bpix;
 	unsigned long compression;
-#if defined(CONFIG_PXA250)
+#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS
 	struct pxafb_info *fbi = &panel_info.pxa;
 #elif defined(CONFIG_MPC823)
 	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
@@ -656,7 +656,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 #if !defined(CONFIG_MCC200)
 	/* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */
 	if (bmp_bpix == 8) {
-#if defined(CONFIG_PXA250)
+#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS
 		cmap = (ushort *)fbi->palette;
 #elif defined(CONFIG_MPC823)
 		cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
@@ -745,7 +745,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 			WATCHDOG_RESET();
 			for (j = 0; j < width; j++) {
 				if (bpix != 16) {
-#if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)
+#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS || defined(CONFIG_ATMEL_LCD)
 					*(fb++) = *(bmap++);
 #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
 					*(fb++) = 255 - *(bmap++);
include/lcd.h +1 -1
index 1f85daa..cd9d49d 100644
@@ -87,7 +87,7 @@ typedef struct vidinfo {
 	u_char	vl_wbf;		/* Wait between frames */
 } vidinfo_t;
 
-#elif defined CONFIG_PXA250
+#elif defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS
 /*
  * PXA LCD DMA descriptor
  */
Signature · 1 line
1.7.1
#1 lore raw

PATCH 2/5 PXA: Add hardware init helper macros

This patch adds macros for the following purposes:
- GPIO configuration
- SDRAM configuration
- Wakeup
- Clock configuration
- Interrupt controller configuration
These macros are intended to replace numerous copies of the same code.

---
 arch/arm/include/asm/arch-pxa/macro.h |  324 +++++++++++++++++++++++++++++++++
 1 files changed, 324 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-pxa/macro.h
arch/arm/include/asm/arch-pxa/macro.h new file +324 -0
new file mode 100644
index 0000000..035a57e
@@ -0,0 +1,324 @@
+/*
+ * arch/arm/include/asm/arch-pxa/macro.h
+ *
+ * Copyright (C) 2010 Marek Vasut <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_PXA_MACRO_H__
+#define __ASM_ARCH_PXA_MACRO_H__
+#ifdef __ASSEMBLY__
+
+#include <asm/macro.h>
+#include <asm/arch/pxa-regs.h>
+
+/*
+ * This macro performs a 32bit write to a memory location and makes sure the
+ * write operation really happened by performing a read back.
+ *
+ * Clobbered regs: r4, r5
+ */
+.macro	write32rb addr, data
+	ldr	r4, =\addr
+	ldr	r5, =\data
+	str	r5, [r4]
+	ldr	r5, [r4]
+.endm
+
+/*
+ * This macro waits according to OSCR incrementation
+ *
+ * Clobbered regs: r4, r5, r6
+ */
+.macro	pxa_wait_ticks ticks
+	ldr	r4, =OSCR
+	mov	r5, #0
+	str	r5, [r4]
+	ldr	r5, =\ticks
+1:
+	ldr	r6, [r4]
+	cmp	r5, r6
+	bgt	1b
+.endm
+
+/*
+ * This macro sets up the GPIO pins of the PXA2xx/PXA3xx CPU
+ *
+ * Clobbered regs: r4, r5
+ */
+.macro	pxa_gpio_setup
+	write32	GPSR0, CONFIG_SYS_GPSR0_VAL
+	write32	GPSR1, CONFIG_SYS_GPSR1_VAL
+	write32	GPSR2, CONFIG_SYS_GPSR2_VAL
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
+	write32	GPSR3, CONFIG_SYS_GPSR3_VAL
+#endif
+
+	write32	GPCR0, CONFIG_SYS_GPCR0_VAL
+	write32	GPCR1, CONFIG_SYS_GPCR1_VAL
+	write32	GPCR2, CONFIG_SYS_GPCR2_VAL
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
+	write32	GPCR3, CONFIG_SYS_GPCR3_VAL
+#endif
+
+	write32	GPDR0, CONFIG_SYS_GPDR0_VAL
+	write32	GPDR1, CONFIG_SYS_GPDR1_VAL
+	write32	GPDR2, CONFIG_SYS_GPDR2_VAL
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
+	write32	GPDR3, CONFIG_SYS_GPDR3_VAL
+#endif
+
+	write32	GAFR0_L, CONFIG_SYS_GAFR0_L_VAL
+	write32	GAFR0_U, CONFIG_SYS_GAFR0_U_VAL
+	write32	GAFR1_L, CONFIG_SYS_GAFR1_L_VAL
+	write32	GAFR1_U, CONFIG_SYS_GAFR1_U_VAL
+	write32	GAFR2_L, CONFIG_SYS_GAFR2_L_VAL
+	write32	GAFR2_U, CONFIG_SYS_GAFR2_U_VAL
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
+	write32	GAFR3_L, CONFIG_SYS_GAFR3_L_VAL
+	write32	GAFR3_U, CONFIG_SYS_GAFR3_U_VAL
+#endif
+
+	write32	PSSR, CONFIG_SYS_PSSR_VAL
+.endm
+
+/*
+ * This macro sets up the Memory controller of the PXA2xx CPU
+ *
+ * Clobbered regs: r3, r4, r5
+ */
+.macro	pxa_mem_setup
+	/* This comes handy when setting MDREFR */
+	ldr	r3, =MEMC_BASE
+
+	/*
+	 * 1) Initialize Asynchronous static memory controller
+	 */
+
+	/* MSC0: nCS(0,1) */
+	write32rb	(MEMC_BASE + MSC0_OFFSET), CONFIG_SYS_MSC0_VAL
+	/* MSC1: nCS(2,3) */
+	write32rb	(MEMC_BASE + MSC1_OFFSET), CONFIG_SYS_MSC1_VAL
+	/* MSC2: nCS(4,5) */
+	write32rb	(MEMC_BASE + MSC2_OFFSET), CONFIG_SYS_MSC2_VAL
+
+	/*
+	 * 2) Initialize Card Interface
+	 */
+
+	/* MECR: Memory Expansion Card Register */
+	write32rb	(MEMC_BASE + MECR_OFFSET), CONFIG_SYS_MECR_VAL
+	/* MCMEM0: Card Interface slot 0 timing */
+	write32rb	(MEMC_BASE + MCMEM0_OFFSET), CONFIG_SYS_MCMEM0_VAL
+	/* MCMEM1: Card Interface slot 1 timing */
+	write32rb	(MEMC_BASE + MCMEM1_OFFSET), CONFIG_SYS_MCMEM1_VAL
+	/* MCATT0: Card Interface Attribute Space Timing, slot 0 */
+	write32rb	(MEMC_BASE + MCATT0_OFFSET), CONFIG_SYS_MCATT0_VAL
+	/* MCATT1: Card Interface Attribute Space Timing, slot 1 */
+	write32rb	(MEMC_BASE + MCATT1_OFFSET), CONFIG_SYS_MCATT1_VAL
+	/* MCIO0: Card Interface I/O Space Timing, slot 0 */
+	write32rb	(MEMC_BASE + MCIO0_OFFSET), CONFIG_SYS_MCIO0_VAL
+	/* MCIO1: Card Interface I/O Space Timing, slot 1 */
+	write32rb	(MEMC_BASE + MCIO1_OFFSET), CONFIG_SYS_MCIO1_VAL
+
+	/*
+	 * 3) Configure Fly-By DMA register
+	 */
+
+	write32rb	(MEMC_BASE + FLYCNFG_OFFSET), CONFIG_SYS_FLYCNFG_VAL
+
+	/*
+	 * 4) Initialize Timing for Sync Memory (SDCLK0)
+	 */
+
+	/*
+	 * Before accessing MDREFR we need a valid DRI field, so we set
+	 * this to power on defaults + DRI field.
+	 */
+	ldr	r5, [r3, #MDREFR_OFFSET]
+	bic	r5, r5, #0x0ff
+	bic	r5, r5, #0xf00	/* MDREFR user config with zeroed DRI */
+
+	ldr	r4, =CONFIG_SYS_MDREFR_VAL
+	mov	r6, r4
+	lsl	r4, #20
+	lsr	r4, #20		/* Get a valid DRI field */
+
+	orr	r5, r5, r4	/* MDREFR user config with correct DRI */
+
+	orr	r5, #MDREFR_K0RUN
+	orr	r5, #MDREFR_SLFRSH
+	bic	r5, #MDREFR_APD
+	bic	r5, #MDREFR_E1PIN
+
+	str	r5, [r3, #MDREFR_OFFSET]
+	ldr	r4, [r3, #MDREFR_OFFSET]
+
+	/*
+	 * 5) Initialize Synchronous Static Memory (Flash/Peripherals)
+	 */
+
+	/* Initialize SXCNFG register. Assert the enable bits.
+	 *
+	 * Write SXMRS to cause an MRS command to all enabled banks of
+	 * synchronous static memory. Note that SXLCR need not be written
+	 * at this time.
+	 */
+	write32rb	(MEMC_BASE + SXCNFG_OFFSET), CONFIG_SYS_SXCNFG_VAL
+
+	/*
+	 * 6) Initialize SDRAM
+	 */
+
+	bic	r6, #MDREFR_SLFRSH
+	str	r6, [r3, #MDREFR_OFFSET]
+	ldr	r4, [r3, #MDREFR_OFFSET]
+
+	orr	r6, #MDREFR_E1PIN
+	str	r6, [r3, #MDREFR_OFFSET]
+	ldr	r4, [r3, #MDREFR_OFFSET]
+
+	/*
+	 * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure
+	 *    but not enable each SDRAM partition pair.
+	 */
+
+	/* Fetch platform value of MDCNFG */
+	ldr	r4, =CONFIG_SYS_MDCNFG_VAL
+	/* Disable all sdram banks */
+	bic	r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
+	bic	r4, r4, #(MDCNFG_DE2|MDCNFG_DE3)
+	/* Write initial value of MDCNFG, w/o enabling sdram banks */
+	str	r4, [r3, #MDCNFG_OFFSET]
+	ldr	r4, [r3, #MDCNFG_OFFSET]
+
+	/* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */
+	pxa_wait_ticks	0x300
+
+	/*
+	 * 8) Trigger a number (usually 8) refresh cycles by attempting
+	 *    non-burst read or write accesses to disabled SDRAM, as commonly
+	 *    specified in the power up sequence documented in SDRAM data
+	 *    sheets. The address(es) used for this purpose must not be
+	 *    cacheable.
+	 */
+
+	ldr	r4, =CONFIG_SYS_DRAM_BASE
+.rept 9
+	str	r5, [r4]
+.endr
+
+	/*
+	 * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1).
+	 */
+
+	ldr	r5, =CONFIG_SYS_MDCNFG_VAL
+	ldr	r4, =(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3)
+	and	r5, r5, r4
+	ldr     r4, [r3, #MDCNFG_OFFSET]
+	orr	r4, r4, r5
+	str     r4, [r3, #MDCNFG_OFFSET]
+	ldr     r4, [r3, #MDCNFG_OFFSET]
+
+	/*
+	 * 10) Write MDMRS.
+	 */
+
+	ldr     r4, =CONFIG_SYS_MDMRS_VAL
+	str     r4, [r3, #MDMRS_OFFSET]
+	ldr     r4, [r3, #MDMRS_OFFSET]
+
+	/*
+	 * 11) Enable APD
+	 */
+
+	ldr	r4, [r3, #MDREFR_OFFSET]
+	and	r6, r6, #MDREFR_APD
+	orr	r4, r4, r6
+	str	r4, [r3, #MDREFR_OFFSET]
+	ldr	r4, [r3, #MDREFR_OFFSET]
+.endm
+
+/*
+ * This macro tests if the CPU woke up from sleep and eventually resumes
+ *
+ * Clobbered regs: r4, r5
+ */
+.macro	pxa_wakeup
+	ldr	r4, =RCSR
+	ldr	r5, [r4]
+	and	r5, r5, #(RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR)
+	str	r5, [r4]
+	teq	r5, #RCSR_SMR
+
+	bne	pxa_wakeup_exit
+
+	ldr	r4, =PSSR
+	mov	r5, #PSSR_PH
+	str	r5, [r4]
+
+	ldr	r4, =PSPR
+	ldr	pc, [r4]
+pxa_wakeup_exit:
+.endm
+
+/*
+ * This macro disables all interupts on PXA2xx/PXA3xx CPU
+ *
+ * Clobbered regs: r4, r5
+ */
+.macro	pxa_intr_setup
+	write32	ICLR, 0
+	write32	ICMR, 0
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
+	write32	ICLR2, 0
+	write32	ICMR2, 0
+#endif
+.endm
+
+/*
+ * This macro configures clock on PXA2xx/PXA3xx CPU
+ *
+ * Clobbered regs: r4, r5
+ */
+.macro	pxa_clock_setup
+	/* Disable the peripheral clocks, and set the core clock frequency */
+
+	/* Turn Off ALL on-chip peripheral clocks for re-configuration */
+	write32	CKEN, CONFIG_SYS_CKEN
+
+	/* Write CCCR */
+	write32	CCCR, CONFIG_SYS_CCCR
+
+#ifdef CONFIG_RTC
+	/* enable the 32Khz oscillator for RTC and PowerManager */
+	write32	OSCC, #OSCC_OON
+	ldr	r4, =OSCC
+
+	/* Spin here until OSCC.OOK get set, meaning the PLL has settled. */
+2:
+	ldr	r5, [r4]
+	ands	r5, r5, #1
+	beq	2b
+#endif
+.endm
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_PXA_MACRO_H__ */
Signature · 1 line
1.7.1
#2 lore raw

PATCH 3/5 PXA: Add PWM2 and PWM3 regs to pxa-regs.h

In reply to Marek Vasut
---
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)
arch/arm/include/asm/arch-pxa/pxa-regs.h +9 -1
index cd7b7f9..d442fb0 100644
@@ -1132,10 +1132,18 @@ typedef void		(*ExcpHndlr) (void) ;
 #define PWM_PWDUTY0	__REG(0x40B00004)  /* PWM 0 Duty Cycle Register */
 #define PWM_PERVAL0	__REG(0x40B00008)  /* PWM 0 Period Control Register */
 
-#define PWM_CTRL1	__REG(0x40C00000)  /* PWM 1Control Register */
+#define PWM_CTRL1	__REG(0x40C00000)  /* PWM 1 Control Register */
 #define PWM_PWDUTY1	__REG(0x40C00004)  /* PWM 1 Duty Cycle Register */
 #define PWM_PERVAL1	__REG(0x40C00008)  /* PWM 1 Period Control Register */
 
+#define PWM_CTRL2	__REG(0x40B00010)  /* PWM 2 Control Register */
+#define PWM_PWDUTY2	__REG(0x40B00014)  /* PWM 2 Duty Cycle Register */
+#define PWM_PERVAL2	__REG(0x40B00018)  /* PWM 2 Period Control Register */
+
+#define PWM_CTRL3	__REG(0x40C00010)  /* PWM 3 Control Register */
+#define PWM_PWDUTY3	__REG(0x40C00014)  /* PWM 3 Duty Cycle Register */
+#define PWM_PERVAL3	__REG(0x40C00018)  /* PWM 3 Period Control Register */
+
 /*
  * Interrupt Controller
  */
Signature · 1 line
1.7.1
#3 lore raw

PATCH 4/5 PXA: Add OneNAND booting support to start.S

In reply to Marek Vasut
---
 arch/arm/cpu/pxa/start.S |   48 +++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 43 insertions(+), 5 deletions(-)
arch/arm/cpu/pxa/start.S +43 -5
index e07c8c2..8010b0e 100644
@@ -34,6 +34,25 @@
 
 .globl _start
 _start: b	reset
+#ifdef CONFIG_PRELOADER
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+
+_hang:
+	.word	do_hang
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678	/* now 16*4=64 */
+#else
 	ldr	pc, _undefined_instruction
 	ldr	pc, _software_interrupt
 	ldr	pc, _prefetch_abort
@@ -49,6 +68,7 @@ _data_abort:		.word data_abort
 _not_used:		.word not_used
 _irq:			.word irq
 _fiq:			.word fiq
+#endif	/* CONFIG_PRELOADER */
 
 	.balignl 16,0xdeadbeef
 
@@ -117,8 +137,10 @@ reset:
 relocate:				/* relocate U-Boot to RAM	    */
 	adr	r0, _start		/* r0 <- current position of code   */
 	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
+#ifndef	CONFIG_PRELOADER
 	cmp	r0, r1			/* don't reloc during debug	    */
 	beq	stack_setup
+#endif
 
 	ldr	r2, _armboot_start
 	ldr	r3, _bss_start
@@ -135,28 +157,37 @@ copy_loop:
 	/* Set up the stack						    */
 stack_setup:
 	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
-	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area			    */
-	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo			    */
+#ifdef CONFIG_PRELOADER
+	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
+#else
+	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area		    */
+	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo		    */
 #ifdef CONFIG_USE_IRQ
 	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 #endif /* CONFIG_USE_IRQ */
 	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
 	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
+#endif
 
 clear_bss:
 	ldr	r0, _bss_start		/* find start of bss segment	    */
 	ldr	r1, _bss_end		/* stop here			    */
 	mov	r2, #0x00000000		/* clear			    */
 
+#ifndef CONFIG_PRELOADER
 clbss_l:str	r2, [r0]		/* clear loop...		    */
 	add	r0, r0, #4
 	cmp	r0, r1
 	ble	clbss_l
+#endif
 
 	ldr	pc, _start_armboot
 
+#ifdef CONFIG_ONENAND_IPL
+_start_armboot: .word start_oneboot
+#else
 _start_armboot: .word start_armboot
-
+#endif
 
 /****************************************************************************/
 /*									    */
@@ -296,7 +327,7 @@ setspeed_done:
 */
 	mov	pc, lr
 
-
+#ifndef CONFIG_PRELOADER
 /****************************************************************************/
 /*									    */
 /* Interrupt handling							    */
@@ -394,6 +425,7 @@ setspeed_done:
 	.macro get_fiq_stack			@ setup FIQ stack
 	ldr	sp, FIQ_STACK_START
 	.endm
+#endif	/* CONFIG_PRELOADER */
 
 
 /****************************************************************************/
@@ -402,6 +434,12 @@ setspeed_done:
 /*									    */
 /****************************************************************************/
 
+#ifdef CONFIG_PRELOADER
+	.align	5
+do_hang:
+	ldr	sp, _TEXT_BASE			/* use 32 words abort stack */
+	bl	hang				/* hang and never return */
+#else	/* !CONFIG_PRELOADER */
 	.align	5
 undefined_instruction:
 	get_bad_stack
@@ -461,7 +499,7 @@ fiq:
 	get_bad_stack
 	bad_save_user_regs
 	bl	do_fiq
-
+#endif	/* CONFIG_PRELOADER */
 #endif /* CONFIG_USE_IRQ */
 
 /****************************************************************************/
Signature · 1 line
1.7.1
#4 lore raw

PATCH 5/5 PXA: PXA3xx NAND Driver

In reply to Marek Vasut

From: Compulab uboot <none@none>

---
 drivers/mtd/nand/Makefile      |    1 +
 drivers/mtd/nand/pxa3xx_nand.c |  848 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 849 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/Makefile +1 -0
index 28f27da..cd840cd 100644
@@ -50,6 +50,7 @@ COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
+COBJS-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
 endif
 
 COBJS	:= $(COBJS-y)
drivers/mtd/nand/pxa3xx_nand.c new file +848 -0

848 lines not on this page · raw message

Signature · 1 line
1.7.1
#5 lore raw

PATCH 5/5 PXA: PXA3xx NAND Driver

Quoted 1 line · Marek Vasut

From: Compulab uboot <none@none>

Hmm?

Quoted 29 lines
---
 drivers/mtd/nand/Makefile      |    1 +
 drivers/mtd/nand/pxa3xx_nand.c |  848 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 849 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/Makefile +1 -0
index 28f27da..cd840cd 100644
@@ -50,6 +50,7 @@ COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
+COBJS-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
 endif
 
 COBJS	:= $(COBJS-y)
drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
new file mode 100644
index 0000000..380c918
@@ -0,0 +1,848 @@
+/*
+ * drivers/mtd/nand/pxa3xx_nand.c
+ *
+ * Copyright ? 2005 Intel Corporation

drivers/mtd/nand/pxa3xx_nand.c line 14

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+ * Copyright ? 2006 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND)

The makefile already limits compilation of this file to when CONFIG_NAND_PXA3XX is defined.

drivers/mtd/nand/pxa3xx_nand.c line 15

Quoted 1 line
drivers/mtd/nand/pxa3xx_nand.c new file +1 -0
+#ifdef CONFIG_NEW_NAND_CODE

Hmm?

Quoted 5 lines
drivers/mtd/nand/pxa3xx_nand.c new file +5 -0
+#define WAIT_EVENT_TIMEOUT	(2 * CONFIG_SYS_HZ/10)
+
+static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event)
+{
+	int timeout = WAIT_EVENT_TIMEOUT;

drivers/mtd/nand/pxa3xx_nand.c line 167

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+	uint32_t ndsr;
+
+	while (timeout--) {
+		ndsr = NDSR & NDSR_MASK;
+		if (ndsr & event) {
+			NDSR = ndsr;
+			return 0;
+		}
+		udelay(10);
+	}

You're defining WAIT_EVENT_TIMEOUT in terms of CONFIG_SYS_HZ ticks (which are supposed to be 1ms, but in any case you should only use CONFIG_SYS_HZ when you're interacting with get_ticks() or similar), but you're interpreting it as a number of 10us intervals.

drivers/mtd/nand/pxa3xx_nand.c line 207

Quoted 12 lines
drivers/mtd/nand/pxa3xx_nand.c new file +12 -0
+	if (info->col_addr_cycles == 2) {
+		/* large block, 2 cycles for column address
+		 * row address starts from 3rd cycle
+		 */
+		info->ndcb1 |= page_addr << 16;
+		if (info->row_addr_cycles == 3)
+			info->ndcb2 = (page_addr >> 16) & 0xff;
+	} else
+		/* small block, 1 cycles for column address
+		 * row address starts from 2nd cycle
+		 */
+		info->ndcb1 = page_addr << 8;

If you put braces on one half of the if, please put it on the other half (and also when you have a multi-line body even if it's technically only one statement).

drivers/mtd/nand/pxa3xx_nand.c line 256

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+/* calculate delta between OSCR values start and now  */
+static unsigned long get_delta(unsigned long start)
+{
+	unsigned long cur = OSCR;
+
+	if(cur < start) /* OSCR overflowed */
+		return (cur + (start^0xffffffff));
+	else
+		return (cur - start);
+}

What's wrong with get_ticks()?

Quoted 5 lines
drivers/mtd/nand/pxa3xx_nand.c new file +5 -0
+
+/* wait_event with timeout */
+static unsigned int wait_event(unsigned long event)
+{
+	unsigned long ndsr, timeout, start = OSCR;

drivers/mtd/nand/pxa3xx_nand.c line 271

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+
+	if(!event)
+		return 0xff000000;
+
+	if(event & (NDSR_CS0_CMDD | NDSR_CS0_BBD))
+		timeout = CONFIG_SYS_NAND_PROG_ERASE_TO * OSCR_CLK_FREQ;
+	else
+		timeout = CONFIG_SYS_NAND_OTHER_TO * OSCR_CLK_FREQ;
+
+	while(1) {

Space after keywords like "if" and "while".

Quoted 16 lines
drivers/mtd/nand/pxa3xx_nand.c new file +16 -0
+static int pxa3xx_nand_do_cmd(struct pxa3xx_nand_info *info, uint32_t event)
+{
+	unsigned int status;
+
+	if (write_cmd(info)) {
+		info->retcode = ERR_SENDCMD;
+		goto fail_stop;
+	}
+
+	info->state = STATE_CMD_HANDLE;
+
+	status = wait_event(event);
+	if (status & (NDSR_RDDREQ | NDSR_DBERR)) {
+		if (status & NDSR_DBERR)
+			info->retcode = ERR_DBERR;
+

drivers/mtd/nand/pxa3xx_nand.c line 384

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+		info->state = STATE_PIO_READING;
+	} else if (status & NDSR_WRDREQ) {
+		info->state = STATE_PIO_WRITING;
+	} else if (status & (NDSR_CS0_BBD | NDSR_CS0_CMDD)) {
+		if (status & NDSR_CS0_BBD)
+			info->retcode = ERR_BBERR;
+
+		info->state = STATE_READY;
+	}
+/*	NDSR = status; */

Why commented out?

drivers/mtd/nand/pxa3xx_nand.c line 395

Quoted 4 lines
drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
+fail_stop:
+	NDCR &= ~NDCR_ND_RUN;
+	udelay(10);
+	return -ETIMEDOUT;

Why is the udelay needed?

drivers/mtd/nand/pxa3xx_nand.c line 514

Quoted 2 lines
drivers/mtd/nand/pxa3xx_nand.c new file +2 -0
+	default:
+		printk(KERN_ERR "non-supported command.\n");

That's a bit vague -- tell the user this message comes from the NAND driver, and what the bad command is.

drivers/mtd/nand/pxa3xx_nand.c line 584

Quoted 7 lines
drivers/mtd/nand/pxa3xx_nand.c new file +7 -0
+/*
+ * not required for Monahans DFC
+ */
+static void pxa3xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	return;
+}

Just don't provide it at all.

Quoted 24 lines
drivers/mtd/nand/pxa3xx_nand.c new file +24 -0
+static int __readid(struct pxa3xx_nand_info *info, uint32_t *id)
+{
+	const struct pxa3xx_nand_flash *f = info->flash_info;
+	const struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
+	uint8_t  id_buff[8];
+	int i;
+	unsigned long *long_buf;
+
+	if (prepare_other_cmd(info, cmdset->read_id)) {
+		printk(KERN_ERR "failed to prepare command\n");
+		return -EINVAL;
+	}
+
+	/* Send command */
+	if (write_cmd(info))
+		goto fail_timeout;
+
+	/* Wait for CMDDM(command done successfully) */
+	if (wait_for_event(info, NDSR_RDDREQ))
+		goto fail_timeout;
+
+	for (i = 0; i < 8; i += 4) {
+		long_buf = (unsigned long *) &id_buff[i];
+		*long_buf = NDDB;

drivers/mtd/nand/pxa3xx_nand.c line 666

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+	}
+	*id = id_buff[0] | (id_buff[1] << 8);
+	return 0;
+
+fail_timeout:
+	NDCR &= ~NDCR_ND_RUN;
+	udelay(10);
+	return -ETIMEDOUT;
+}
+

Why is this done differently here than when the generic layer issues a READID command?

Quoted 12 lines
drivers/mtd/nand/pxa3xx_nand.c new file +12 -0
+static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
+				    const struct pxa3xx_nand_flash *f)
+{
+	uint32_t ndcr = 0x00000FFF; /* disable all interrupts */
+
+	if (f->page_size != 2048 && f->page_size != 512)
+		return -EINVAL;
+
+	if (f->flash_width != 16 && f->flash_width != 8)
+		return -EINVAL;
+
+	/* calculate flash information */

drivers/mtd/nand/pxa3xx_nand.c line 688

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+	info->oob_size = (f->page_size == 2048) ? 64 : 16;
+	info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
+
+	/* calculate addressing information */
+	info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
+
+	if (f->num_blocks * f->page_per_block > 65536)
+		info->row_addr_cycles = 3;
+	else
+		info->row_addr_cycles = 2;

This looks duplicative of pxa3xx_nand_detect_config.

Quoted 7 lines
drivers/mtd/nand/pxa3xx_nand.c new file +7 -0
+	/* set info fields needed to __readid */
+	info->flash_info = &default_flash;
+	info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+	info->reg_ndcr = ndcr;
+
+	if (__readid(info, &id))
+		return -ENODEV;

drivers/mtd/nand/pxa3xx_nand.c line 738

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+
+	/* Lookup the flash id */
+	id = (id >> 8) & 0xff;		/* device id is byte 2 */
+
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (id == nand_flash_ids[i].id) {
+			type =  &nand_flash_ids[i];
+			break;
+		}
+	}

Why do you need to do this here? The generic NAND code will look this up.

drivers/mtd/nand/pxa3xx_nand.c line 769

Quoted 9 lines
drivers/mtd/nand/pxa3xx_nand.c new file +9 -0
+static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info)
+{
+	uint32_t id = -1;
+	int i;
+
+	if (pxa3xx_nand_detect_config(info) == 0)
+		return 0;
+
+	for (i = 0; i < 1; ++i) {

What's this one-iteration loop for?

drivers/mtd/nand/pxa3xx_nand.c line 779

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+		if (pxa3xx_nand_config_flash(info, info->flash_info))
+			continue;
+
+		if (__readid(info, &id))
+			continue;
+
+		return 0;
+	}
+
+	printf("failed to detect configured nand flash; found %04x instead of\n", id);

Instead of what? Did you really "find" anything in this case?

pxa3xx_nand_detect_config already does the __readid, why do you need to do it again here? You don't do anything with the id if __readid succeeds.

drivers/mtd/nand/pxa3xx_nand.c line 788

Quoted 9 lines
drivers/mtd/nand/pxa3xx_nand.c new file +9 -0
+
+	return -ENODEV;
+}
+
+static struct nand_ecclayout hw_smallpage_ecclayout = {
+	.eccbytes = 6,
+	.eccpos = {8, 9, 10, 11, 12, 13 },
+	.oobfree = { {2, 6} }
+};

Normally with small page NAND the bad block marker is at byte 5, at least with 8-bit chips.

If you really have bad block information somewhere else, you'll want to provide a non-default badblock_pattern.

drivers/mtd/nand/pxa3xx_nand.c line 848

Quoted 4 lines
drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
+#else
+#error "U-Boot legacy NAND support not available for Monahans DFC."
+#endif
+#endif

Legacy NAND has been removed from u-boot altogether. Please don't reintroduce references to it.

-Scott

#6 lore raw

PATCH 5/5 PXA: PXA3xx NAND Driver

Dne P? 9. ?ervence 2010 22:04:00 Scott Wood napsal(a):

Quoted 4 lines · Marek Vasut
Quoted 1 line

From: Compulab uboot <none@none>

Hmm?

Well I was unable to figure out who was the author, though the license of the code is GPL so it should be OK ? I'll try poking around a little bit more, but it's unlikely I'll find some more info.

I dropped this patch from -next until this is fixed so -next can be pulled.

Thanks for reviewing.

Quoted 312 lines
Quoted 36 lines

---

 drivers/mtd/nand/Makefile      |    1 +
 drivers/mtd/nand/pxa3xx_nand.c |  848
 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 849
 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/Makefile +1 -0
index 28f27da..cd840cd 100644
@@ -50,6 +50,7 @@ COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 
 COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
 
+COBJS-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
 

endif

COBJS := $(COBJS-y)

(quoted diff) +0 -0

b/drivers/mtd/nand/pxa3xx_nand.c new file mode 100644 index 0000000..380c918

drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
@@ -0,0 +1,848 @@
+/*
+ * drivers/mtd/nand/pxa3xx_nand.c
+ *
+ * Copyright ? 2005 Intel Corporation

drivers/mtd/nand/pxa3xx_nand.c line 14

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+ * Copyright ? 2006 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND)

The makefile already limits compilation of this file to when CONFIG_NAND_PXA3XX is defined.

drivers/mtd/nand/pxa3xx_nand.c line 15

Quoted 1 line
drivers/mtd/nand/pxa3xx_nand.c new file +1 -0
+#ifdef CONFIG_NEW_NAND_CODE

Hmm?

Quoted 5 lines
drivers/mtd/nand/pxa3xx_nand.c new file +5 -0
+#define WAIT_EVENT_TIMEOUT	(2 * CONFIG_SYS_HZ/10)
+
+static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event)
+{
+	int timeout = WAIT_EVENT_TIMEOUT;

drivers/mtd/nand/pxa3xx_nand.c line 167

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+	uint32_t ndsr;
+
+	while (timeout--) {
+		ndsr = NDSR & NDSR_MASK;
+		if (ndsr & event) {
+			NDSR = ndsr;
+			return 0;
+		}
+		udelay(10);
+	}

You're defining WAIT_EVENT_TIMEOUT in terms of CONFIG_SYS_HZ ticks (which are supposed to be 1ms, but in any case you should only use CONFIG_SYS_HZ when you're interacting with get_ticks() or similar), but you're interpreting it as a number of 10us intervals.

drivers/mtd/nand/pxa3xx_nand.c line 207

Quoted 12 lines
drivers/mtd/nand/pxa3xx_nand.c new file +12 -0
+	if (info->col_addr_cycles == 2) {
+		/* large block, 2 cycles for column address
+		 * row address starts from 3rd cycle
+		 */
+		info->ndcb1 |= page_addr << 16;
+		if (info->row_addr_cycles == 3)
+			info->ndcb2 = (page_addr >> 16) & 0xff;
+	} else
+		/* small block, 1 cycles for column address
+		 * row address starts from 2nd cycle
+		 */
+		info->ndcb1 = page_addr << 8;

If you put braces on one half of the if, please put it on the other half (and also when you have a multi-line body even if it's technically only one statement).

drivers/mtd/nand/pxa3xx_nand.c line 256

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+/* calculate delta between OSCR values start and now  */
+static unsigned long get_delta(unsigned long start)
+{
+	unsigned long cur = OSCR;
+
+	if(cur < start) /* OSCR overflowed */
+		return (cur + (start^0xffffffff));
+	else
+		return (cur - start);
+}

What's wrong with get_ticks()?

Quoted 5 lines
drivers/mtd/nand/pxa3xx_nand.c new file +5 -0
+
+/* wait_event with timeout */
+static unsigned int wait_event(unsigned long event)
+{
+	unsigned long ndsr, timeout, start = OSCR;

drivers/mtd/nand/pxa3xx_nand.c line 271

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+
+	if(!event)
+		return 0xff000000;
+
+	if(event & (NDSR_CS0_CMDD | NDSR_CS0_BBD))
+		timeout = CONFIG_SYS_NAND_PROG_ERASE_TO * OSCR_CLK_FREQ;
+	else
+		timeout = CONFIG_SYS_NAND_OTHER_TO * OSCR_CLK_FREQ;
+
+	while(1) {

Space after keywords like "if" and "while".

Quoted 16 lines
drivers/mtd/nand/pxa3xx_nand.c new file +1 -0
+static int pxa3xx_nand_do_cmd(struct pxa3xx_nand_info *info, uint32_t

event) +{

drivers/mtd/nand/pxa3xx_nand.c new file +14 -0
+	unsigned int status;
+
+	if (write_cmd(info)) {
+		info->retcode = ERR_SENDCMD;
+		goto fail_stop;
+	}
+
+	info->state = STATE_CMD_HANDLE;
+
+	status = wait_event(event);
+	if (status & (NDSR_RDDREQ | NDSR_DBERR)) {
+		if (status & NDSR_DBERR)
+			info->retcode = ERR_DBERR;
+

drivers/mtd/nand/pxa3xx_nand.c line 384

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+		info->state = STATE_PIO_READING;
+	} else if (status & NDSR_WRDREQ) {
+		info->state = STATE_PIO_WRITING;
+	} else if (status & (NDSR_CS0_BBD | NDSR_CS0_CMDD)) {
+		if (status & NDSR_CS0_BBD)
+			info->retcode = ERR_BBERR;
+
+		info->state = STATE_READY;
+	}
+/*	NDSR = status; */

Why commented out?

drivers/mtd/nand/pxa3xx_nand.c line 395

Quoted 4 lines
drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
+fail_stop:
+	NDCR &= ~NDCR_ND_RUN;
+	udelay(10);
+	return -ETIMEDOUT;

Why is the udelay needed?

drivers/mtd/nand/pxa3xx_nand.c line 514

Quoted 2 lines
drivers/mtd/nand/pxa3xx_nand.c new file +2 -0
+	default:
+		printk(KERN_ERR "non-supported command.\n");

That's a bit vague -- tell the user this message comes from the NAND driver, and what the bad command is.

drivers/mtd/nand/pxa3xx_nand.c

Quoted 7 lines
drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
+/*
+ * not required for Monahans DFC
+ */
+static void pxa3xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned

int ctrl) +{

drivers/mtd/nand/pxa3xx_nand.c new file +2 -0
+	return;
+}

Just don't provide it at all.

Quoted 24 lines
drivers/mtd/nand/pxa3xx_nand.c new file +24 -0
+static int __readid(struct pxa3xx_nand_info *info, uint32_t *id)
+{
+	const struct pxa3xx_nand_flash *f = info->flash_info;
+	const struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
+	uint8_t  id_buff[8];
+	int i;
+	unsigned long *long_buf;
+
+	if (prepare_other_cmd(info, cmdset->read_id)) {
+		printk(KERN_ERR "failed to prepare command\n");
+		return -EINVAL;
+	}
+
+	/* Send command */
+	if (write_cmd(info))
+		goto fail_timeout;
+
+	/* Wait for CMDDM(command done successfully) */
+	if (wait_for_event(info, NDSR_RDDREQ))
+		goto fail_timeout;
+
+	for (i = 0; i < 8; i += 4) {
+		long_buf = (unsigned long *) &id_buff[i];
+		*long_buf = NDDB;

drivers/mtd/nand/pxa3xx_nand.c line 666

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+	}
+	*id = id_buff[0] | (id_buff[1] << 8);
+	return 0;
+
+fail_timeout:
+	NDCR &= ~NDCR_ND_RUN;
+	udelay(10);
+	return -ETIMEDOUT;
+}
+

Why is this done differently here than when the generic layer issues a READID command?

Quoted 12 lines
drivers/mtd/nand/pxa3xx_nand.c new file +12 -0
+static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
+				    const struct pxa3xx_nand_flash *f)
+{
+	uint32_t ndcr = 0x00000FFF; /* disable all interrupts */
+
+	if (f->page_size != 2048 && f->page_size != 512)
+		return -EINVAL;
+
+	if (f->flash_width != 16 && f->flash_width != 8)
+		return -EINVAL;
+
+	/* calculate flash information */

drivers/mtd/nand/pxa3xx_nand.c line 688

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+	info->oob_size = (f->page_size == 2048) ? 64 : 16;
+	info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
+
+	/* calculate addressing information */
+	info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
+
+	if (f->num_blocks * f->page_per_block > 65536)
+		info->row_addr_cycles = 3;
+	else
+		info->row_addr_cycles = 2;

This looks duplicative of pxa3xx_nand_detect_config.

Quoted 7 lines
drivers/mtd/nand/pxa3xx_nand.c new file +7 -0
+	/* set info fields needed to __readid */
+	info->flash_info = &default_flash;
+	info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+	info->reg_ndcr = ndcr;
+
+	if (__readid(info, &id))
+		return -ENODEV;

drivers/mtd/nand/pxa3xx_nand.c line 738

Quoted 10 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+
+	/* Lookup the flash id */
+	id = (id >> 8) & 0xff;		/* device id is byte 2 */
+
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (id == nand_flash_ids[i].id) {
+			type =  &nand_flash_ids[i];
+			break;
+		}
+	}

Why do you need to do this here? The generic NAND code will look this up.

drivers/mtd/nand/pxa3xx_nand.c line 769

Quoted 9 lines
drivers/mtd/nand/pxa3xx_nand.c new file +9 -0
+static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info)
+{
+	uint32_t id = -1;
+	int i;
+
+	if (pxa3xx_nand_detect_config(info) == 0)
+		return 0;
+
+	for (i = 0; i < 1; ++i) {

What's this one-iteration loop for?

Quoted 11 lines
drivers/mtd/nand/pxa3xx_nand.c new file +10 -0
+		if (pxa3xx_nand_config_flash(info, info->flash_info))
+			continue;
+
+		if (__readid(info, &id))
+			continue;
+
+		return 0;
+	}
+
+	printf("failed to detect configured nand flash; found %04x instead

of\n", id);

Instead of what? Did you really "find" anything in this case?

pxa3xx_nand_detect_config already does the __readid, why do you need to do it again here? You don't do anything with the id if __readid succeeds.

drivers/mtd/nand/pxa3xx_nand.c line 788

Quoted 9 lines
drivers/mtd/nand/pxa3xx_nand.c new file +9 -0
+
+	return -ENODEV;
+}
+
+static struct nand_ecclayout hw_smallpage_ecclayout = {
+	.eccbytes = 6,
+	.eccpos = {8, 9, 10, 11, 12, 13 },
+	.oobfree = { {2, 6} }
+};

Normally with small page NAND the bad block marker is at byte 5, at least with 8-bit chips.

If you really have bad block information somewhere else, you'll want to provide a non-default badblock_pattern.

drivers/mtd/nand/pxa3xx_nand.c line 848

Quoted 4 lines
drivers/mtd/nand/pxa3xx_nand.c new file +4 -0
+#else
+#error "U-Boot legacy NAND support not available for Monahans DFC."
+#endif
+#endif

Legacy NAND has been removed from u-boot altogether. Please don't reintroduce references to it.

-Scott

#7 lore raw

PATCH 5/5 PXA: PXA3xx NAND Driver

Quoted 9 lines · Marek Vasut

Dne P? 9. ?ervence 2010 22:04:00 Scott Wood napsal(a):

Quoted 4 lines · Marek Vasut
Quoted 1 line

From: Compulab uboot <none@none>

Hmm?

Well I was unable to figure out who was the author, though the license of the code is GPL so it should be OK ? I'll try poking around a little bit more, but it's unlikely I'll find some more info.

I'd just describe where it came from in the commit message, rather than use a From: line. The code is (partly?) from them, but the patch is from you.

-Scott