Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- nand-as3525.c
- /*
- * Copyright (C) 2006 Austriamicrosystems Corporation
- *
- * 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
- */
- #include <inttypes.h>
- #include "config.h"
- #include "nand-as3525v2.h"
- #include "system.h"
- //#include "nand.h"
- #define CCU_IO ( (AS352X_CCU_BASE) + 0x0C)
- /*
- * hardware specific access to control-lines
- */
- #define NAND_CTL_SETNCE 1
- /* Deselect the chip by setting nCE to high */
- #define NAND_CTL_CLRNCE 2
- /* Select the command latch by setting CLE to high */
- #define NAND_CTL_SETCLE 3
- /* Deselect the command latch by setting CLE to low */
- #define NAND_CTL_CLRCLE 4
- /* Select the address latch by setting ALE to high */
- #define NAND_CTL_SETALE 5
- /* Deselect the address latch by setting ALE to low */
- #define NAND_CTL_CLRALE 6
- /* Set write protection by setting WP to high. Not used! */
- #define NAND_CTL_SETWP 7
- /* Clear write protection by setting WP to low. Not used! */
- #define NAND_CTL_CLRWP 8
- #define NAF_X8_X16_CODE 0x03 /* only for big block nand */
- /*
- * Standard NAND flash commands
- */
- #define NAND_CMD_READ0 0
- #define NAND_CMD_READ1 1
- #define NAND_CMD_PAGEPROG 0x10
- #define NAND_CMD_READOOB 0x50
- #define NAND_CMD_ERASE1 0x60
- #define NAND_CMD_STATUS 0x70
- #define NAND_CMD_STATUS_MULTI 0x71
- #define NAND_CMD_SEQIN 0x80
- #define NAND_CMD_READID 0x90
- #define NAND_CMD_ERASE2 0xd0
- #define NAND_CMD_RESET 0xff
- /* Extended commands for large page devices */
- #define NAND_CMD_READSTART 0x30
- #define NAND_CMD_CACHEDPROG 0x15
- /* Status bits */
- #define NAND_STATUS_FAIL 0x01
- #define NAND_STATUS_FAIL_N1 0x02
- #define NAND_STATUS_TRUE_READY 0x20
- #define NAND_STATUS_READY 0x40
- #define NAND_STATUS_WP 0x80
- /**
- * Power bit in NAF mode register.
- **/
- #define NAF_POWER_ON 0x0C
- #define NAF_POWER_OFF 0x00
- /**
- * NAF Config register bits.
- **/
- #define NAF_X16 0x00000001
- #define NAF_FIFO_ENABLE 0x00000004
- #define NAF_DMA_ON 0x00000008
- #define NAF_READ_STROBE_H 0x00000020 /* read strobe high is 4 PLCK cycles */
- #define NAF_READ_STROBE_L 0x00000400 /* read strobe low is 5 PLCK cycles */
- #define NAF_WRITE_STROBE_H 0x00003000 /* write strobe high is 4 PCLK cycles */
- #define NAF_WRITE_STROBE_L 0x00040000 /* write strobe high is 4 PCLK cycles */
- #define NAF_STROBE_CONFIG \
- ( NAF_READ_STROBE_H | NAF_READ_STROBE_L | NAF_WRITE_STROBE_H | \
- NAF_WRITE_STROBE_L )
- /**
- * NAF modi
- **/
- #define NAF_MODE_CLE 1<<0
- #define NAF_MODE_ALE 1<<1
- #define NAF_MODE_NCE 1<<4
- #define NAF_MODE_WP 1<<7
- #define NAF_MODE_DATA_READ_NO_ECC 0x14
- #define NAF_MODE_DATA_WRITE_ECC_RESET 0xF4
- #define NAF_MODE_DATA_WRITE_NO_ECC 0x94
- /*
- * chip R/B detection
- */
- static int as352x_read_status;
- static int as352x_nand_ready(void)
- {
- return ( ( rreg16( NAF_STATUS ) & 0x0080 ) == 0x0080 );
- }
- static int as352x_nand_strobe(void)
- {
- return ( ( rreg16( NAF_STATUS ) & 0x0100 ) == 0x0100 );
- }
- static int as352x_fifo_isfull(void)
- {
- return ( ( rreg16( NAF_STATUS ) & 0x01000 ) );
- }
- static int as352x_fifo_isempty(void)
- {
- return ( ( rreg16( NAF_STATUS ) & 0x0200 ) );
- }
- /**
- * nand_read_byte - [DEFAULT] read one byte from the chip
- * @mtd: MTD device structure
- *
- * Default read function for 8bit buswith
- */
- uint8_t as352x_nand_read_byte(void)
- {
- uint8_t data = 0;
- unsigned char ct = 255;
- wreg8 ( NAF_CONTROL, 0x1 ); /* generate read strobe */
- while (!as352x_nand_strobe() && ct > 0)
- {
- udelay(10);
- ct--;
- }
- data = rreg16( NAF_DATA );
- if (as352x_read_status)
- data |= 0x80;
- return data;
- }
- /**
- * nand_write_byte - [DEFAULT] write one byte to the chip
- * @mtd: MTD device structure
- * @byte: pointer to data byte to write
- *
- * Default write function for 8it buswith
- */
- static void as352x_nand_write_byte(uint8_t byte)
- {
- unsigned char ct = 255;
- wreg16( NAF_DATA, byte );
- while (!as352x_nand_strobe() && ct > 0)
- {
- udelay(10);
- ct--;
- }
- }
- void as352x_nand_wait_fifo_empty(void)
- {
- while ( ( rreg16( NAF_STATUS ) & 0x0004 ) != 0x0004 ) ;
- /* wait for got empty and ready */
- }
- /**
- * nand_write_buf - [DEFAULT] write buffer to chip
- * @mtd: MTD device structure
- * @buf: data buffer
- * @len: number of bytes to write
- *
- * Default write function for 8bit buswith
- */
- static void as352x_nand_write_buf(const uint8_t *buf, int len)
- {
- int i;
- uint32_t *p =(uint32_t *)buf;
- /* struct nand_chip *this = mtd->priv;
- * unused, incomplete
- */
- len /=4;
- wreg8( NAF_CLEAR, 0x7f );
- wreg32( NAF_WORDS, len );
- for (i=0; i<len; i++)
- {
- while (as352x_fifo_isfull());
- wreg32( NAF_FIFODATA, p[i] );
- }
- as352x_nand_wait_fifo_empty();
- }
- /**
- * nand_read_buf - [DEFAULT] read chip data into buffer
- * @mtd: MTD device structure
- * @buf: buffer to store date
- * @len: number of bytes to read
- *
- * Default read function for 8bit buswith
- */
- void as352x_nand_read_buf(uint8_t *buf, int len)
- {
- int i;
- /* struct nand_chip *this = mtd->priv;
- * unused, incomplete
- */
- uint32_t *p =(uint32_t *)buf;
- len /=4;
- wreg8( NAF_CLEAR, 0x7f );
- wreg32( NAF_WORDS, len );
- for (i=0; i<len; i++)
- {
- while (as352x_fifo_isempty());
- p[i] = rreg32( NAF_FIFODATA );
- }
- as352x_nand_wait_fifo_empty( );
- }
- /**
- * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * Default verify function for 8bit buswith
- */
- static int nand_verify_buf(const uint8_t *buf, int len)
- {
- int i;
- /* struct nand_chip *this = mtd->priv;
- * unused, incomplete
- */
- for (i=0; i<len; i++)
- if (buf[i] != as352x_nand_read_byte())
- return -14; /*EFAULT; - Bad address */
- return 0;
- }
- static void as352x_nand_hwcontrol(int cmd)
- {
- /* struct nand_chip *this = mtd->priv;
- * ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
- * unused, incomplete
- */
- switch (cmd)
- {
- case NAND_CTL_SETCLE:
- {
- set_reg_bits16 ( NAF_MODE, NAF_MODE_CLE);
- }
- break;
- case NAND_CTL_CLRCLE:
- clr_reg_bits16( NAF_MODE, NAF_MODE_CLE);
- break;
- case NAND_CTL_SETALE:
- {
- set_reg_bits16 ( NAF_MODE, NAF_MODE_ALE);
- }
- break;
- case NAND_CTL_CLRALE:
- clr_reg_bits16( NAF_MODE, NAF_MODE_ALE);
- break;
- case NAND_CTL_SETNCE:
- set_reg_bits16 ( NAF_MODE, NAF_MODE_NCE);
- break;
- case NAND_CTL_CLRNCE:
- clr_reg_bits16( NAF_MODE, NAF_MODE_NCE);
- break;
- case NAND_CTL_SETWP:
- set_reg_bits16 ( NAF_MODE, NAF_MODE_WP);
- break;
- case NAND_CTL_CLRWP:
- clr_reg_bits16( NAF_MODE, NAF_MODE_WP);
- break;
- }
- }
- void cmd_read_test(void)
- {
- int column = 1;
- int page_addr = 1;
- wreg8( NAF_MASK, 0xFF );
- wreg8( NAF_CLEAR, 0x7f );
- wreg8( NAF_MODE,NAF_MODE_DATA_READ_NO_ECC);
- as352x_nand_hwcontrol(NAND_CTL_CLRWP);
- /* Begin command latch cycle */
- as352x_nand_hwcontrol(NAND_CTL_SETCLE);
- /* Write out the command to the device. */
- as352x_nand_write_byte(NAND_CMD_READ0);
- /* End command latch cycle */
- as352x_nand_hwcontrol(NAND_CTL_CLRCLE);
- if (column != -1 || page_addr != -1)
- {
- as352x_nand_hwcontrol(NAND_CTL_SETALE);
- /* Serially input address */
- if (column != -1)
- {
- /* Adjust columns for 16 bit buswidth */
- /* if (this->options & NAND_BUSWIDTH_16)
- column >>= 1;*/
- as352x_nand_write_byte(column & 0xff);
- as352x_nand_write_byte(column >> 8);
- }
- if (page_addr != -1)
- {
- as352x_nand_write_byte((unsigned char) (page_addr & 0xff));
- as352x_nand_write_byte((unsigned char) ((page_addr >> 8) & 0xff));
- /* One more address cycle for devices > 128MiB */
- //if (this->chipsize > (128 << 20))
- as352x_nand_write_byte((unsigned char) ((page_addr >> 16) & 0xff));
- }
- /* Latch in address */
- as352x_nand_hwcontrol(NAND_CTL_CLRALE);
- }
- //case NAND_CMD_READ0:
- /* Begin command latch cycle */
- as352x_nand_hwcontrol(NAND_CTL_SETCLE);
- /* Write out the start read command */
- as352x_nand_write_byte(NAND_CMD_READSTART);
- /* End command latch cycle */
- as352x_nand_hwcontrol(NAND_CTL_CLRCLE);
- /* Fall through into ready check */
- /* This applies to read commands */
- /*
- * If we don't have access to the busy pin, we apply the
- given
- * command delay
- */
- if (!as352x_nand_ready())
- {
- udelay (30);
- return;
- }
- }
- /**
- * nand_command_lp - [DEFAULT] Send command to NAND large page device
- * @mtd: MTD device structure
- * @command: the command to be sent
- * @column: the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
- *
- * Send command to NAND device. This is the version for the new large
- page devices
- * We dont have the seperate regions as we have in the small page
- devices.
- * We must emulate NAND_CMD_READOOB to keep the code compatible.
- *
- */
- #if 0
- static void as352x_nand_command_lp (struct mtd_info *mtd, unsigned
- command, int column, int page_addr)
- {
- register struct nand_chip *this = mtd->priv;
- /* Emulate NAND_CMD_READOOB */
- if (command == NAND_CMD_READOOB) {
- column += mtd->oobblock;
- command = NAND_CMD_READ0;
- }
- as352x_read_status =0;
- switch (command)
- {
- case NAND_CMD_SEQIN:
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- {
- wreg8( NAF_MASK, 0xFF );
- wreg8( NAF_CLEAR, 0x7f );
- }
- case NAND_CMD_CACHEDPROG:
- case NAND_CMD_PAGEPROG:
- {
- this->hwcontrol(mtd, NAND_CTL_SETWP);
- }
- break;
- case NAND_CMD_READ0:
- wreg8( NAF_MASK, 0xFF );
- wreg8( NAF_CLEAR, 0x7f );
- wreg8( NAF_MODE,NAF_MODE_DATA_READ_NO_ECC);
- default:
- this->hwcontrol(mtd, NAND_CTL_CLRWP);
- }
- /* Begin command latch cycle */
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- /* Write out the command to the device. */
- this->write_byte(mtd, command);
- /* End command latch cycle */
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- if (column != -1 || page_addr != -1) {
- this->hwcontrol(mtd, NAND_CTL_SETALE);
- /* Serially input address */
- if (column != -1) {
- /* Adjust columns for 16 bit buswidth */
- if (this->options & NAND_BUSWIDTH_16)
- column >>= 1;
- this->write_byte(mtd, column & 0xff);
- this->write_byte(mtd, column >> 8);
- }
- if (page_addr != -1) {
- this->write_byte(mtd, (unsigned char) (page_addr
- & 0xff));
- this->write_byte(mtd, (unsigned char)
- ((page_addr >> 8) & 0xff));
- /* One more address cycle for devices > 128MiB
- */
- if (this->chipsize > (128 << 20))
- this->write_byte(mtd, (unsigned char)
- ((page_addr >> 16) & 0xff));
- }
- /* Latch in address */
- this->hwcontrol(mtd, NAND_CTL_CLRALE);
- }
- /*
- * program and erase have their own busy handlers
- * status and sequential in needs no delay
- */
- switch (command) {
- case NAND_CMD_SEQIN:
- {
- wreg8( NAF_MODE, NAF_MODE_DATA_WRITE_ECC_RESET );
- break;
- }
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- break;
- case NAND_CMD_STATUS:
- as352x_read_status =1;
- break;
- case NAND_CMD_CACHEDPROG:
- case NAND_CMD_PAGEPROG:
- wreg8( NAF_MODE, NAF_MODE_DATA_WRITE_NO_ECC );
- break;
- case NAND_CMD_RESET:
- if (this->dev_ready)
- break;
- udelay(this->chip_delay);
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- this->write_byte(mtd, NAND_CMD_STATUS);
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- while ( !(this->read_byte(mtd) & 0x40));
- return;
- case NAND_CMD_READ0:
- /* Begin command latch cycle */
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- /* Write out the start read command */
- this->write_byte(mtd, NAND_CMD_READSTART);
- /* End command latch cycle */
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- /* Fall through into ready check */
- /* This applies to read commands */
- default:
- /*
- * If we don't have access to the busy pin, we apply the
- given
- * command delay
- */
- if (!this->dev_ready) {
- udelay (this->chip_delay);
- return;
- }
- }
- /* Apply this short delay always to ensure that we do wait tWB
- in
- * any case on any machine. */
- ndelay (1000);
- /* wait until command is processed */
- while (!this->dev_ready(mtd));
- }
- #endif
- void board_nand_init(void)
- {
- // clear all NAF chip select bits
- clr_reg_bits32( CCU_IO , ( CCU_IO_NAF_CE_LINE_0 | CCU_IO_NAF_CE_LINE_1
- | CCU_IO_NAF_CE_LINE_2 | CCU_IO_NAF_CE_LINE_3
- ) );
- set_reg_bits32( CCU_IO , CCU_IO_NAF_CE_LINE_0 );
- /* configure NAF */
- wreg8( NAF_MODE, NAF_POWER_ON ); /* turn power on */
- wreg8( NAF_MASK, 0xFF );
- wreg8( NAF_CLEAR, 0x7f ); /* clear any pending error indication */
- /* configure fifo on but dma still off */
- wreg32( NAF_CONFIG, NAF_STROBE_CONFIG | NAF_FIFO_ENABLE);
- /* 2. change into read mode */
- wreg8 ( NAF_MODE, NAF_MODE_DATA_READ_NO_ECC );
- // nand->options = NAND_SAMSUNG_LP_OPTIONS;
- // nand->eccmode = NAND_ECC_SOFT;
- // nand->hwcontrol = as352x_nand_hwcontrol;
- // nand->dev_ready = as352x_nand_ready;
- // nand->chip_delay = 18;
- // nand->read_byte = as352x_nand_read_byte;
- // nand->write_byte = as352x_nand_write_byte;
- // nand->read_buf = as352x_nand_read_buf;
- // nand->write_buf = as352x_nand_write_buf;
- // nand->cmdfunc = as352x_nand_command_lp;
- }
- nand-as2535.h
- /*
- * (C) Copyright 2006
- * Copyright (C) 2006 Austriamicrosystems, by thomas.luo
- *
- * 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 __NAND_AS352X_H__
- #define __NAND_AS352X_H__
- /* AS352X only supports 512 Byte HW ECC */
- #define AS352X_ECCSIZE 512
- #define AS352X_ECCBYTES 3
- #include <inttypes.h>
- /* AS352X device base addresses */
- /*
- ------------------------------------------------------------------------
- * AS352X Registers
- *
- ------------------------------------------------------------------------
- *
- */
- /* APB */
- #define AS352X_NAND_FLASH_BASE 0xC8000000
- #define AS352X_SD_MCI_BASE 0xC8020000
- #define AS352X_CCU_BASE 0xC8100000
- //#define CCU_IO ( (AS352X_CCU_BASE) + 0x0C)
- /**
- * Reset Control Lines in CCU_SRC register
- **/
- #define CCU_SRC_NAF_EN ( 1 << 15 )
- #define CCU_SRC_SDMCI_EN ( 1 << 14 )
- /**
- * Chip select lines for NAF. Use these constants to select/deselct the
- CE lines
- * for NAND flashes in Register CCU_IO.
- **/
- #define CCU_IO_NAF_CE_LINE_0 ( 0 << 7 )
- #define CCU_IO_NAF_CE_LINE_1 ( 1 << 7 )
- #define CCU_IO_NAF_CE_LINE_2 ( 2 << 7 )
- #define CCU_IO_NAF_CE_LINE_3 ( 3 << 7 )
- /**
- * Chip select lines for NAF. Use these constants to select/deselct the
- CE lines
- * for NAND flashes in Register CCU_IO.
- **/
- #define CCU_IO_NAF_CE_LINE_0 ( 0 << 7 )
- #define CCU_IO_NAF_CE_LINE_1 ( 1 << 7 )
- #define CCU_IO_NAF_CE_LINE_2 ( 2 << 7 )
- #define CCU_IO_NAF_CE_LINE_3 ( 3 << 7 )
- /* --- are disabled after reset --- */
- #define CGU_MCI_CLOCK_ENABLE ( 1 << 15 ) /* mmc + sd */
- #define CGU_NAF_CLOCK_ENABLE ( 1 << 14 ) /* naf */
- /* ----------------------- defines
- ---------------------------------------- */
- #define NAF_CONFIG ( (AS352X_NAND_FLASH_BASE) + 0x00 )
- #define NAF_CONTROL ( (AS352X_NAND_FLASH_BASE) + 0x04 )
- #define NAF_ECC ( (AS352X_NAND_FLASH_BASE) + 0x08 )
- #define NAF_DATA ( (AS352X_NAND_FLASH_BASE) + 0x0C )
- #define NAF_MODE ( (AS352X_NAND_FLASH_BASE) + 0x10 )
- #define NAF_STATUS ( (AS352X_NAND_FLASH_BASE) + 0x14 )
- #define NAF_MASK ( (AS352X_NAND_FLASH_BASE) + 0x18 )
- #define NAF_FIFODATA ( (AS352X_NAND_FLASH_BASE) + 0x1C )
- #define NAF_WORDS ( (AS352X_NAND_FLASH_BASE) + 0x20 )
- #define NAF_CLEAR ( (AS352X_NAND_FLASH_BASE) + 0x24 )
- #define NAF_TEST ( (AS352X_NAND_FLASH_BASE) + 0x28 )
- #define set_reg_bits32( registerAddress, value ) \
- ( *( (volatile uint32_t *)(registerAddress) ) |= ( (uint32_t)(value) ) )
- #define clr_reg_bits32( registerAddress, value ) \
- ( *( (volatile uint32_t *)(registerAddress) ) &= ( ~( (uint32_t)(value) ) ) )
- #define rreg32( registerAddress ) \
- ( *( ( const volatile uint32_t * )( registerAddress ) ) )
- #define wreg32( registerAddress, value ) \
- ( *( (volatile uint32_t *)(registerAddress) ) = ( (uint32_t)(value) ) )
- #define rreg16( registerAddress ) \
- ( *( ( const volatile uint16_t * )( registerAddress ) ) )
- #define wreg16( registerAddress, value ) \
- ( *( (volatile uint16_t *)(registerAddress) ) = ( (uint16_t)(value) ) )
- #define set_reg_bits16( registerAddress, value ) \
- ( *( (volatile uint16_t *)(registerAddress) ) |= ( (uint16_t)(value) ) )
- #define clr_reg_bits16( registerAddress, value ) \
- ( *( (volatile uint16_t *)(registerAddress) ) &= ( ~( (uint16_t)(value) ) ) )
- #define rreg8( registerAddress ) \
- ( *( ( const volatile uint8_t * )( registerAddress ) ) )
- #define wreg8( registerAddress, value ) \
- ( *( (volatile uint8_t *)(registerAddress) ) = ( (uint8_t)(value) ) )
- #define set_reg_bits8( registerAddress, value ) \
- ( *( (volatile uint8_t *)(registerAddress) ) |= ( (uint8_t)(value) ) )
- #define clr_reg_bits8( registerAddress, value ) \
- ( *( (volatile uint8_t *)(registerAddress) ) &= ( ~( (uint8_t)(value) ) ) )
- /* Wait until rINTPND is changed for the case that the ISR is very
- short. */
- void board_nand_init(void);
- uint8_t as352x_nand_read_byte(void);
- void as352x_nand_read_buf(uint8_t *buf, int len);
- void cmd_read_test(void);
- #endif /*__NAND_AS3525_H__*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement