1 /* 2 * (C) Copyright 2008 Stefan Roese <sr@denx.de>, DENX Software Engineering 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 17 * MA 02111-1307 USA 18 */ 19 20 #include <common.h> 21 #include <asm/io.h> 22 #include <linux/mtd/mtd.h> 23 #include <linux/mtd/onenand.h> 24 #include "vct.h" 25 26 #define BURST_SIZE_WORDS 4 27 28 static u16 ebi_nand_read_word(void __iomem *addr) 29 { 30 reg_write(EBI_CPU_IO_ACCS(EBI_BASE), (EXT_DEVICE_CHANNEL_2 | (u32)addr)); 31 ebi_wait(); 32 33 return reg_read(EBI_IO_ACCS_DATA(EBI_BASE)) >> 16; 34 } 35 36 static void ebi_nand_write_word(u16 data, void __iomem * addr) 37 { 38 ebi_wait(); 39 reg_write(EBI_IO_ACCS_DATA(EBI_BASE), (data << 16)); 40 reg_write(EBI_CPU_IO_ACCS(EBI_BASE), 41 EXT_DEVICE_CHANNEL_2 | EBI_CPU_WRITE | (u32)addr); 42 ebi_wait(); 43 } 44 45 /* 46 * EBI initialization for OneNAND FLASH access 47 */ 48 int ebi_init_onenand(void) 49 { 50 reg_write(EBI_DEV1_CONFIG1(EBI_BASE), 0x83000); 51 52 reg_write(EBI_DEV2_CONFIG1(EBI_BASE), 0x00403002); 53 reg_write(EBI_DEV2_CONFIG2(EBI_BASE), 0x50); 54 55 reg_write(EBI_DEV3_CONFIG1(EBI_BASE), 0x00403002); 56 reg_write(EBI_DEV3_CONFIG2(EBI_BASE), 0x0); /* byte/word ordering */ 57 58 reg_write(EBI_DEV2_TIM1_RD1(EBI_BASE), 0x00504000); 59 reg_write(EBI_DEV2_TIM1_RD2(EBI_BASE), 0x00001000); 60 reg_write(EBI_DEV2_TIM1_WR1(EBI_BASE), 0x12002223); 61 reg_write(EBI_DEV2_TIM1_WR2(EBI_BASE), 0x3FC02220); 62 reg_write(EBI_DEV3_TIM1_RD1(EBI_BASE), 0x00504000); 63 reg_write(EBI_DEV3_TIM1_RD2(EBI_BASE), 0x00001000); 64 reg_write(EBI_DEV3_TIM1_WR1(EBI_BASE), 0x05001000); 65 reg_write(EBI_DEV3_TIM1_WR2(EBI_BASE), 0x00010200); 66 67 reg_write(EBI_DEV2_TIM_EXT(EBI_BASE), 0xFFF00000); 68 reg_write(EBI_DEV2_EXT_ACC(EBI_BASE), 0x0FFFFFFF); 69 70 reg_write(EBI_DEV3_TIM_EXT(EBI_BASE), 0xFFF00000); 71 reg_write(EBI_DEV3_EXT_ACC(EBI_BASE), 0x0FFFFFFF); 72 73 /* prepare DMA configuration for EBI */ 74 reg_write(EBI_DEV3_FIFO_CONFIG(EBI_BASE), 0x0101ff00); 75 76 /* READ only no byte order change, TAG 1 used */ 77 reg_write(EBI_DEV3_DMA_CONFIG2(EBI_BASE), 0x00000004); 78 79 reg_write(EBI_TAG1_SYS_ID(EBI_BASE), 0x0); /* SCC DMA channel 0 */ 80 reg_write(EBI_TAG2_SYS_ID(EBI_BASE), 0x1); 81 reg_write(EBI_TAG3_SYS_ID(EBI_BASE), 0x2); 82 reg_write(EBI_TAG4_SYS_ID(EBI_BASE), 0x3); 83 84 return 0; 85 } 86 87 static void *memcpy_16_from_onenand(void *dst, const void *src, unsigned int len) 88 { 89 void *ret = dst; 90 u16 *d = dst; 91 u16 *s = (u16 *)src; 92 93 len >>= 1; 94 while (len-- > 0) 95 *d++ = ebi_nand_read_word(s++); 96 97 return ret; 98 } 99 100 static void *memcpy_32_from_onenand(void *dst, const void *src, unsigned int len) 101 { 102 void *ret = dst; 103 u32 *d = (u32 *)dst; 104 u32 s = (u32)src; 105 u32 bytes_per_block = BURST_SIZE_WORDS * sizeof(int); 106 u32 n_blocks = len / bytes_per_block; 107 u32 block = 0; 108 u32 burst_word; 109 110 for (block = 0; block < n_blocks; block++) { 111 /* Trigger read channel 3 */ 112 reg_write(EBI_CPU_IO_ACCS(EBI_BASE), 113 (EXT_DEVICE_CHANNEL_3 | (s + (block * bytes_per_block)))); 114 /* Poll status to see whether read has finished */ 115 ebi_wait(); 116 117 /* Squirrel the data away in a safe place */ 118 for (burst_word = 0; burst_word < BURST_SIZE_WORDS; burst_word++) 119 *d++ = reg_read(EBI_IO_ACCS_DATA(EBI_BASE)); 120 } 121 122 return ret; 123 } 124 125 static void *memcpy_16_to_onenand(void *dst, const void *src, unsigned int len) 126 { 127 void *ret = dst; 128 u16 *d = dst; 129 u16 *s = (u16 *)src; 130 131 len >>= 1; 132 while (len-- > 0) 133 ebi_nand_write_word(*s++, d++); 134 135 return ret; 136 } 137 138 static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area) 139 { 140 struct onenand_chip *this = mtd->priv; 141 142 if (ONENAND_CURRENT_BUFFERRAM(this)) { 143 if (area == ONENAND_DATARAM) 144 return mtd->writesize; 145 if (area == ONENAND_SPARERAM) 146 return mtd->oobsize; 147 } 148 149 return 0; 150 } 151 152 static int ebi_read_bufferram(struct mtd_info *mtd, loff_t addr, int area, 153 unsigned char *buffer, int offset, 154 size_t count) 155 { 156 struct onenand_chip *this = mtd->priv; 157 void __iomem *bufferram; 158 159 bufferram = this->base + area; 160 bufferram += onenand_bufferram_offset(mtd, area); 161 162 if (count < 4) 163 memcpy_16_from_onenand(buffer, bufferram + offset, count); 164 else 165 memcpy_32_from_onenand(buffer, bufferram + offset, count); 166 167 return 0; 168 } 169 170 static int ebi_write_bufferram(struct mtd_info *mtd, loff_t addr, int area, 171 const unsigned char *buffer, int offset, 172 size_t count) 173 { 174 struct onenand_chip *this = mtd->priv; 175 void __iomem *bufferram; 176 177 bufferram = this->base + area; 178 bufferram += onenand_bufferram_offset(mtd, area); 179 180 memcpy_16_to_onenand(bufferram + offset, buffer, count); 181 182 return 0; 183 } 184 185 void onenand_board_init(struct mtd_info *mtd) 186 { 187 struct onenand_chip *chip = mtd->priv; 188 189 /* 190 * Insert board specific OneNAND access functions 191 */ 192 chip->read_word = ebi_nand_read_word; 193 chip->write_word = ebi_nand_write_word; 194 195 chip->read_bufferram = ebi_read_bufferram; 196 chip->write_bufferram = ebi_write_bufferram; 197 } 198