public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Scott Wood <scottwood@freescale.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 08/13 v3] ARM: OMAP3: Add NAND support
Date: Thu, 09 Oct 2008 14:47:38 -0500	[thread overview]
Message-ID: <48EE5FDA.7050608@freescale.com> (raw)
In-Reply-To: <48ee46b5.02e2660a.4ba8.5c3b@mx.google.com>

dirk.behme at googlemail.com wrote:
> +unsigned char cs;
> +volatile unsigned long gpmc_cs_base_add;

Make these static.  gpmc_cs_base_add should be a pointer, not "unsigned 
long".  Volatile isn't needed since you use I/O accessors, and 
definitely isn't needed on the address itself.

> +/*
> + * omap_nand_hwcontrol - Set the address pointers corretly for the
> + *			following address/data/command operation
> + */
> +static void omap_nand_hwcontrol(struct mtd_info *mtd, int cmd,
> +				unsigned int ctrl)
> +{
> +	register struct nand_chip *this = mtd->priv;
> +
> +	/* Point the IO_ADDR to DATA and ADDRESS registers instead
> +	   of chip address */
> +	switch (ctrl) {
> +	case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
> +		this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_CMD;
> +		this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
> +		break;
> +	case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
> +		this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_ADR;
> +		this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
> +		break;
> +	case NAND_CTRL_CHANGE | NAND_NCE:
> +		this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
> +		this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
> +		break;
> +	}

IO_ADDR_R never seems to change; you can leave it out of here and 
omap_nand_wait.

> +/*
> + * omap_nand_wait - called primarily after a program/erase operation
> + *			so that we access NAND again only after the device
> + *			is ready again.
> + * @mtd:        MTD device structure
> + * @chip:	nand_chip structure
> + */
> +static int omap_nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
> +{
> +	register struct nand_chip *this = mtd->priv;
> +	int status = 0;
> +
> +	this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_CMD;
> +	this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
> +	/* Send the status command and loop until the device is free */
> +	while (!(status & 0x40)) {
> +		writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W);
> +		status = readb(this->IO_ADDR_R);
> +	}

Maybe should just do this, to avoid changing client-visible state:
writeb(NAND_CMD_STATUS, &gpmc_cs_base_add[GPMC_NAND_CMD]);

No need for the "& 0xFF".

> +	/* Init ECC Control Register */
> +	/* Clear all ECC  | Enable Reg1 */
> +	val = ((0x00000001 << 8) | 0x00000001);
> +	writel(val, GPMC_BASE + GPMC_ECC_CONTROL);
> +	writel(0x3fcff000, GPMC_BASE + GPMC_ECC_SIZE_CONFIG);

Symbolic constants for the bit values would be nice.

> +/*
> + *  omap_calculate_ecc - Generate non-inverted ECC bytes.
> + *
> + *  Using noninverted ECC can be considered ugly since writing a blank
> + *  page ie. padding will clear the ECC bytes. This is no problem as
> + *  long nobody is trying to write data on the seemingly unused page.
> + *  Reading an erased page will produce an ECC mismatch between
> + *  generated and read ECC bytes that has to be dealt with separately.

Where is it dealt with separately?

> +	unsigned long val = 0x0;

Unnecessary initialization.

> +	unsigned long reg;
> +
> +	/* Start Reading from HW ECC1_Result = 0x200 */
> +	reg = (unsigned long) (GPMC_BASE + GPMC_ECC1_RESULT);
> +	val = readl(reg);

readl() takes a pointer.  ARM gets away without a warning here because 
it uses macros rather than inline functions, but it's bad practice.

> +	/* Stop reading anymore ECC vals and clear old results
> +	 * enable will be called if more reads are required */
> +	reg = (unsigned long) (GPMC_BASE + GPMC_ECC_CONFIG);
> +	writel(0x000, reg);

Likewise.

> +void omap_nand_switch_ecc(int hardware)
> +{
> +	struct nand_chip *nand;
> +
> +	if (nand_curr_device < 0 ||
> +	    nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
> +	    !nand_info[nand_curr_device].name) {
> +		printf("Error: Can't switch ecc, no devices available\n");
> +		return;
> +	}
> +
> +	nand = (&nand_info[nand_curr_device])->priv;
> +
> +	if (!hardware) {
> +		nand->ecc.mode = NAND_ECC_SOFT;
> +		nand->ecc.layout = &sw_nand_oob_64;
> +		nand->ecc.size = 256;	/* set default eccsize */
> +		nand->ecc.bytes = 3;
> +		nand->ecc.steps = 8;
> +		nand->ecc.hwctl = 0;
> +		nand->ecc.calculate = nand_calculate_ecc;
> +		nand->ecc.correct = nand_correct_data;
> +	} else {
> +		nand->ecc.mode = NAND_ECC_HW;
> +		nand->ecc.layout = &hw_nand_oob_64;
> +		nand->ecc.size = 512;
> +		nand->ecc.bytes = 3;
> +		nand->ecc.steps = 4;
> +		nand->ecc.hwctl = omap_enable_hwecc;
> +		nand->ecc.correct = omap_correct_data;
> +		nand->ecc.calculate = omap_calculate_ecc;
> +		omap_hwecc_init(nand);
> +	}

Do you need to do anything similar to omap_hwecc_init() when switching 
to SW ECC to tell the hardware to stop doing ECC?

-Scott

  reply	other threads:[~2008-10-09 19:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-09 18:00 [U-Boot] [PATCH 08/13 v3] ARM: OMAP3: Add NAND support dirk.behme at googlemail.com
2008-10-09 19:47 ` Scott Wood [this message]
2008-10-10  6:58   ` Dirk Behme
2008-10-10  8:03     ` Wolfgang Denk
2008-10-10  8:09       ` Dirk Behme
2008-10-10 17:55     ` Scott Wood
2008-10-11  8:55       ` Dirk Behme
2008-10-13 16:00         ` Scott Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48EE5FDA.7050608@freescale.com \
    --to=scottwood@freescale.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox