#ifndef __K9F2G08_S3C_H__ #define __K9F2G08_S3C_H__ #include "s3c2440.h" static inline void bsp_init_nand(void) { unsigned int reg; struct s3c2440_clock_power *clkpwr = s3c2440_get_base_clock_power(); clkpwr->CLKCON |= (1<<4); struct s3c2440_gpio *gpio = s3c2440_get_base_gpio(); struct s3c2440_nand *nand = s3c2440_get_base_nand(); reg = gpio->GPACON; reg |= (1<<22) | (1<<20) | (1<<19) | (1<<18) | (1<<17); gpio->GPACON = reg; nand->NFCONF = (1<<12) | (1<<8) | (1<<4) | (1<<3) |(1<<2) | (1<<5) | (0<<0); nand->NFCONT = 3; } static inline void bsp_nand_set_cs(int level) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); if (level == 0) { nand->NFCONT &= ~(1<<1); // while (nand->NFSTAT & (1<<1)); } else { nand->NFCONT |= 1<<1; // while ((nand->NFSTAT & (1<<1)) == 0); } } static inline void bsp_nand_start_main_ecc(void) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); nand->NFCONT |= (1<<6) | (1<<5); // unlock all nand->NFCONT |= (1<<4); // init ecc nand->NFCONT &= ~(1<<6); // lock spare } static inline void bsp_nand_stop_main_ecc(void) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); nand->NFCONT |= (1<<5); // lock main } static inline void bsp_nand_start_spare_ecc(void) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); nand->NFCONT &= ~(1<<6); // unlock spare } static inline void bsp_nand_stop_spare_ecc(void) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); nand->NFCONT |= (1<<6); // lock spare } static inline int bsp_nand_spare_check_ecc(unsigned short ecc, int *err_byte, int *err_bit) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); unsigned int ecc_wr = ((ecc & 0xFF00) << 8) | (ecc & 0x00FF); nand->NFSECCD = ecc_wr; int err = nand->NFESTAT0; if ((err & (3<<2)) == (0<<2)) // no err return 0; if ((err & (3<<2)) == (1<<2)) { // 1 bit err *err_byte = (err >> 21) & 0x0F; *err_bit = (err >> 18) & 0x07; return 1; } return -1; } static inline int bsp_nand_main_check_ecc(unsigned int ecc, int *err_byte, int *err_bit) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); unsigned int ecc_wr = ((ecc & 0xFF00) << 8) | (ecc & 0x00FF); nand->NFMECCD0 = ecc_wr; ecc_wr = ((ecc & 0xFF000000) >> 8) | ((ecc & 0x00FF0000) >> 16); nand->NFMECCD1 = ecc_wr; int err = nand->NFESTAT0; if ((err & (3<<0)) == (0<<0)) // no err return 0; if ((err & (3<<0)) == (1<<0)) { // no err *err_byte = (err >> 7) & 0x7FF; *err_bit = (err >> 4) & 0x07; return 1; } return -1; } static inline void bsp_nand_write_cmd(unsigned char cmd) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); nand->NFCMD = cmd; } static inline void bsp_nand_write_addr(unsigned char addr) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); nand->NFADDR = addr; } static inline void bsp_nand_write_data32(unsigned int dat) { *(volatile unsigned int *)(&(s3c2440_get_base_nand()->NFDATA)) = dat; } static inline void bsp_nand_write_data16(unsigned short dat) { *(volatile unsigned short *)(&(s3c2440_get_base_nand()->NFDATA)) = dat; } static inline void bsp_nand_write_data8(unsigned char dat) { *(volatile unsigned char *)(&(s3c2440_get_base_nand()->NFDATA)) = dat; } static inline unsigned int bsp_nand_read_data32(void) { return *(volatile unsigned int *)(&(s3c2440_get_base_nand()->NFDATA)); } static inline unsigned short bsp_nand_read_data16(void) { return *(volatile unsigned short *)(&(s3c2440_get_base_nand()->NFDATA)); } static inline unsigned char bsp_nand_read_data8(void) { return *(volatile unsigned char *)(&(s3c2440_get_base_nand()->NFDATA)); } static inline unsigned short bsp_nand_read_spare_ecc0(void) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); return nand->NFSECC & 0xFFFF; } static inline unsigned int bsp_nand_read_main_ecc0(void) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); return nand->NFMECC0; } static inline void bsp_nand_wait_busy(void) { int i; for (i=10; i>0; i--); struct s3c2440_nand *nand = s3c2440_get_base_nand(); while ((nand->NFSTAT & (1<<0)) == 0); } #endif //__K9F2G08_S3C_H__