| 1 | /* |
| 2 | * board.c |
| 3 | * |
| 4 | * Board init routines. |
| 5 | * |
| 6 | * Copyright (C) 2006 Ingenic Semiconductor Inc. |
| 7 | * |
| 8 | */ |
| 9 | #include "common.h" |
| 10 | #include "jz4760.h" |
| 11 | #include "board-jz4760.h" |
| 12 | |
| 13 | void nand_init_4760() |
| 14 | { |
| 15 | REG_NEMC_NFCSR |= NEMC_NFCSR_NFE1 | NEMC_NFCSR_NFCE1; |
| 16 | } |
| 17 | |
| 18 | void cpm_start_all_4760() |
| 19 | { |
| 20 | __cpm_start_all(); |
| 21 | } |
| 22 | |
| 23 | /* |
| 24 | * SD0 ~ SD7, SA0 ~ SA5, CS2#, RD#, WR#, WAIT# |
| 25 | */ |
| 26 | #define __gpio_as_nor() \ |
| 27 | do { \ |
| 28 | /* SD0 ~ SD7, RD#, WR#, CS2#, WAIT# */ \ |
| 29 | REG_GPIO_PXFUNS(0) = 0x084300ff; \ |
| 30 | REG_GPIO_PXTRGC(0) = 0x084300ff; \ |
| 31 | REG_GPIO_PXSELC(0) = 0x084300ff; \ |
| 32 | REG_GPIO_PXPES(0) = 0x084300ff; \ |
| 33 | /* SA0 ~ SA5 */ \ |
| 34 | REG_GPIO_PXFUNS(1) = 0x0000003f; \ |
| 35 | REG_GPIO_PXTRGC(1) = 0x0000003f; \ |
| 36 | REG_GPIO_PXSELC(1) = 0x0000003f; \ |
| 37 | REG_GPIO_PXPES(1) = 0x0000003f; \ |
| 38 | } while (0) |
| 39 | |
| 40 | void gpio_init_4760() |
| 41 | { |
| 42 | __gpio_as_uart0(); |
| 43 | __gpio_as_uart1(); |
| 44 | __gpio_as_uart2(); |
| 45 | __gpio_as_uart3(); |
| 46 | |
| 47 | #ifdef CONFIG_FPGA // if the delay isn't added on FPGA, the first line that uart to print will not be normal. |
| 48 | __gpio_as_nor(); |
| 49 | { |
| 50 | volatile int i=1000; |
| 51 | while(i--); |
| 52 | } |
| 53 | #endif |
| 54 | __gpio_as_nand_16bit(1); |
| 55 | } |
| 56 | |
| 57 | #define MHZ (1000 * 1000) |
| 58 | static inline unsigned int pll_calc_m_n_od(unsigned int speed, unsigned int xtal) |
| 59 | { |
| 60 | const int pll_m_max = 0x7f, pll_m_min = 4; |
| 61 | const int pll_n_max = 0x0f, pll_n_min = 2; |
| 62 | |
| 63 | int od[] = {1, 2, 4, 8}; |
| 64 | int min_od = 0; |
| 65 | |
| 66 | unsigned int plcr_m_n_od = 0; |
| 67 | unsigned int distance; |
| 68 | unsigned int tmp, raw; |
| 69 | |
| 70 | int i, j, k; |
| 71 | int m, n; |
| 72 | |
| 73 | distance = 0xFFFFFFFF; |
| 74 | |
| 75 | for (i = 0; i < sizeof (od) / sizeof(int); i++) { |
| 76 | /* Limit: 500MHZ <= CLK_OUT * OD <= 1500MHZ */ |
| 77 | // if (min_od != 0) |
| 78 | // break; |
| 79 | if ((speed * od[i]) < 500 * MHZ || (speed * od[i]) > 1500 * MHZ) |
| 80 | continue; |
| 81 | for (k = pll_n_min; k <= pll_n_max; k++) { |
| 82 | n = k; |
| 83 | |
| 84 | /* Limit: 1MHZ <= XIN/N <= 50MHZ */ |
| 85 | if ((xtal / n) < (1 * MHZ)) |
| 86 | break; |
| 87 | if ((xtal / n) > (15 * MHZ)) |
| 88 | continue; |
| 89 | |
| 90 | for (j = pll_m_min; j <= pll_m_max; j++) { |
| 91 | m = j*2; |
| 92 | |
| 93 | raw = xtal * m / n; |
| 94 | tmp = raw / od[i]; |
| 95 | |
| 96 | tmp = (tmp > speed) ? (tmp - speed) : (speed - tmp); |
| 97 | |
| 98 | if (tmp < distance) { |
| 99 | distance = tmp; |
| 100 | |
| 101 | plcr_m_n_od = (j << CPM_CPPCR_PLLM_BIT) |
| 102 | | (k << CPM_CPPCR_PLLN_BIT) |
| 103 | | (i << CPM_CPPCR_PLLOD_BIT); |
| 104 | |
| 105 | if (!distance) { /* Match. */ |
| 106 | // serial_puts("right value"); |
| 107 | return plcr_m_n_od; |
| 108 | } |
| 109 | } |
| 110 | } |
| 111 | min_od = od[i]; |
| 112 | } |
| 113 | } |
| 114 | return plcr_m_n_od; |
| 115 | } |
| 116 | |
| 117 | /* TODO: pll_init() need modification. */ |
| 118 | void pll_init_4760() |
| 119 | { |
| 120 | register unsigned int cfcr, plcr1; |
| 121 | int n2FR[9] = { |
| 122 | 0, 0, 1, 2, 3, 0, 4, 0, 5 |
| 123 | }; |
| 124 | |
| 125 | /** divisors, |
| 126 | * for jz4760 ,I:H:H2:P:M:S. |
| 127 | * DIV should be one of [1, 2, 3, 4, 6, 8] like: |
| 128 | * div[6] = {1, 2, 2, 2, 2, 2}; |
| 129 | * div[6] = {1, 3, 6, 6, 6, 6}; |
| 130 | */ |
| 131 | int div[6] = {1, 2, 4, 4, 4, 4}; |
| 132 | |
| 133 | cfcr = CPM_CPCCR_PCS | |
| 134 | (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | |
| 135 | (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | |
| 136 | (n2FR[div[2]] << CPM_CPCCR_H2DIV_BIT) | |
| 137 | (n2FR[div[3]] << CPM_CPCCR_PDIV_BIT) | |
| 138 | (n2FR[div[4]] << CPM_CPCCR_MDIV_BIT) | |
| 139 | (n2FR[div[5]] << CPM_CPCCR_SDIV_BIT); |
| 140 | |
| 141 | if (CFG_EXTAL > 16000000) |
| 142 | cfcr |= CPM_CPCCR_ECS; |
| 143 | else |
| 144 | cfcr &= ~CPM_CPCCR_ECS; |
| 145 | |
| 146 | /* set CPM_CPCCR_MEM only for ddr1 or ddr2 */ |
| 147 | #if defined(CONFIG_DDRC) && (defined(CONFIG_SDRAM_DDR1) || defined(CONFIG_SDRAM_DDR2)) |
| 148 | cfcr |= CPM_CPCCR_MEM; |
| 149 | #else |
| 150 | cfcr &= ~CPM_CPCCR_MEM; |
| 151 | #endif |
| 152 | cfcr |= CPM_CPCCR_CE; |
| 153 | |
| 154 | plcr1 = pll_calc_m_n_od(CFG_CPU_SPEED, CFG_EXTAL); |
| 155 | plcr1 |= (0x20 << CPM_CPPCR_PLLST_BIT) /* PLL stable time */ |
| 156 | | CPM_CPPCR_PLLEN; /* enable PLL */ |
| 157 | |
| 158 | /* init PLL */ |
| 159 | REG_CPM_CPCCR = cfcr; |
| 160 | REG_CPM_CPPCR = plcr1; |
| 161 | |
| 162 | while(!(REG_CPM_CPPSR & (1 << 29))); |
| 163 | |
| 164 | #ifdef DEBUG |
| 165 | serial_puts("REG_CPM_CPCCR = "); |
| 166 | serial_put_hex(REG_CPM_CPCCR); |
| 167 | serial_puts("REG_CPM_CPPCR = "); |
| 168 | serial_put_hex(REG_CPM_CPPCR); |
| 169 | #endif |
| 170 | } |
| 171 | |
| 172 | #if (defined(CONFIG_SDRAM_MDDR)||defined(CONFIG_SDRAM_DDR1)||defined(CONFIG_SDRAM_DDR2)) |
| 173 | void jzmemset(void *dest,int ch,int len) |
| 174 | { |
| 175 | unsigned int *d = (unsigned int *)dest; |
| 176 | int i; |
| 177 | int wd; |
| 178 | |
| 179 | wd = (ch << 24) | (ch << 16) | (ch << 8) | ch; |
| 180 | |
| 181 | for(i = 0;i < len / 32;i++) |
| 182 | { |
| 183 | *d++ = wd; |
| 184 | *d++ = wd; |
| 185 | *d++ = wd; |
| 186 | *d++ = wd; |
| 187 | *d++ = wd; |
| 188 | *d++ = wd; |
| 189 | *d++ = wd; |
| 190 | *d++ = wd; |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | unsigned int gen_verify_data(unsigned int i) |
| 195 | { |
| 196 | i = i/4*0x11111111; |
| 197 | return i; |
| 198 | //return 0xffffffff; |
| 199 | } |
| 200 | |
| 201 | int initdram(int board_type) |
| 202 | { |
| 203 | u32 ddr_cfg; |
| 204 | u32 rows, cols, dw, banks; |
| 205 | unsigned long size; |
| 206 | ddr_cfg = REG_DDRC_CFG; |
| 207 | rows = 12 + ((ddr_cfg & DDRC_CFG_ROW_MASK) >> DDRC_CFG_ROW_BIT); |
| 208 | cols = 8 + ((ddr_cfg & DDRC_CFG_COL_MASK) >> DDRC_CFG_COL_BIT); |
| 209 | |
| 210 | dw = (ddr_cfg & DDRC_CFG_DW) ? 4 : 2; |
| 211 | banks = (ddr_cfg & DDRC_CFG_BA) ? 8 : 4; |
| 212 | |
| 213 | size = (1 << (rows + cols)) * dw * banks; |
| 214 | size *= (DDR_CS1EN + DDR_CS0EN); |
| 215 | |
| 216 | return size; |
| 217 | } |
| 218 | static int dma_check_result(void *src, void *dst, int size,int print_flag) |
| 219 | { |
| 220 | unsigned int addr1, addr2, i, err = 0; |
| 221 | unsigned int data_expect,dsrc,ddst; |
| 222 | |
| 223 | addr1 = (unsigned int)src; |
| 224 | addr2 = (unsigned int)dst; |
| 225 | |
| 226 | for (i = 0; i < size; i += 4) { |
| 227 | data_expect = gen_verify_data(i); |
| 228 | dsrc = REG32(addr1); |
| 229 | ddst = REG32(addr2); |
| 230 | if ((dsrc != data_expect) || (ddst != data_expect)) { |
| 231 | #if DEBUG |
| 232 | serial_put_hex(addr2); |
| 233 | serial_puts("data:"); |
| 234 | serial_put_hex(data_expect); |
| 235 | serial_puts("src"); |
| 236 | serial_put_hex(dsrc); |
| 237 | serial_puts("dst"); |
| 238 | serial_put_hex(ddst); |
| 239 | #endif |
| 240 | err = 1; |
| 241 | if(!print_flag) |
| 242 | return 1; |
| 243 | } |
| 244 | |
| 245 | addr1 += 4; |
| 246 | addr2 += 4; |
| 247 | } |
| 248 | return err; |
| 249 | } |
| 250 | |
| 251 | #if DEBUG |
| 252 | void dump_jz_dma_channel(unsigned int dmanr) |
| 253 | { |
| 254 | |
| 255 | if (dmanr > MAX_DMA_NUM) |
| 256 | return; |
| 257 | serial_puts("REG_DDRC_ST \t\t="); |
| 258 | serial_put_hex(REG_DDRC_ST); |
| 259 | |
| 260 | serial_puts("DMA Registers, Channel "); |
| 261 | serial_put_hex(dmanr); |
| 262 | |
| 263 | serial_puts(" DMACR = "); |
| 264 | serial_put_hex(REG_DMAC_DMACR(dmanr/HALF_DMA_NUM)); |
| 265 | serial_puts(" DSAR = "); |
| 266 | serial_put_hex(REG_DMAC_DSAR(dmanr)); |
| 267 | serial_puts(" DTAR = "); |
| 268 | serial_put_hex(REG_DMAC_DTAR(dmanr)); |
| 269 | serial_puts(" DTCR = "); |
| 270 | serial_put_hex(REG_DMAC_DTCR(dmanr)); |
| 271 | serial_puts(" DRSR = "); |
| 272 | serial_put_hex(REG_DMAC_DRSR(dmanr)); |
| 273 | serial_puts(" DCCSR = "); |
| 274 | serial_put_hex(REG_DMAC_DCCSR(dmanr)); |
| 275 | serial_puts(" DCMD = "); |
| 276 | serial_put_hex(REG_DMAC_DCMD(dmanr)); |
| 277 | serial_puts(" DDA = "); |
| 278 | serial_put_hex(REG_DMAC_DDA(dmanr)); |
| 279 | serial_puts(" DMADBR = "); |
| 280 | serial_put_hex(REG_DMAC_DMADBR(dmanr/HALF_DMA_NUM)); |
| 281 | } |
| 282 | |
| 283 | void dma_nodesc_test_single(int dma_chan, int dma_src_addr, int dma_dst_addr, int size) |
| 284 | { |
| 285 | int dma_src_phys_addr, dma_dst_phys_addr; |
| 286 | |
| 287 | /* Allocate DMA buffers */ |
| 288 | dma_src_phys_addr = dma_src_addr & (~0xa0000000); |
| 289 | dma_dst_phys_addr = dma_dst_addr & (~0xa0000000); |
| 290 | |
| 291 | /* Init DMA module */ |
| 292 | REG_DMAC_DCCSR(dma_chan) = 0; |
| 293 | REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; |
| 294 | REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; |
| 295 | REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; |
| 296 | REG_DMAC_DTCR(dma_chan) = size; |
| 297 | REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT; |
| 298 | REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; |
| 299 | } |
| 300 | |
| 301 | static void ddrc_regs_print(void) |
| 302 | { |
| 303 | serial_puts("\nDDRC REGS:\n"); |
| 304 | serial_puts("REG_DDRC_ST \t\t="); |
| 305 | serial_put_hex(REG_DDRC_ST); |
| 306 | serial_puts("REG_DDRC_CFG \t\t="); |
| 307 | serial_put_hex( REG_DDRC_CFG); |
| 308 | serial_puts("REG_DDRC_CTRL \t\t="); |
| 309 | serial_put_hex(REG_DDRC_CTRL); |
| 310 | serial_puts("REG_DDRC_LMR \t\t="); |
| 311 | serial_put_hex(REG_DDRC_LMR); |
| 312 | serial_puts("REG_DDRC_TIMING1 \t="); |
| 313 | serial_put_hex(REG_DDRC_TIMING1); |
| 314 | serial_puts("REG_DDRC_TIMING2 \t="); |
| 315 | serial_put_hex(REG_DDRC_TIMING2); |
| 316 | serial_puts("REG_DDRC_REFCNT \t\t="); |
| 317 | serial_put_hex(REG_DDRC_REFCNT); |
| 318 | serial_puts("REG_DDRC_DQS \t\t="); |
| 319 | serial_put_hex(REG_DDRC_DQS); |
| 320 | serial_puts("REG_DDRC_DQS_ADJ \t="); |
| 321 | serial_put_hex(REG_DDRC_DQS_ADJ); |
| 322 | serial_puts("REG_DDRC_MMAP0 \t\t="); |
| 323 | serial_put_hex(REG_DDRC_MMAP0); |
| 324 | serial_puts("REG_DDRC_MMAP1 \t\t="); |
| 325 | serial_put_hex(REG_DDRC_MMAP1); |
| 326 | serial_puts("REG_DDRC_MDELAY \t\t="); |
| 327 | serial_put_hex(REG_DDRC_MDELAY); |
| 328 | serial_puts("REG_EMC_PMEMPS2 \t\t="); |
| 329 | serial_put_hex(REG_EMC_PMEMPS2); |
| 330 | } |
| 331 | |
| 332 | static int dma_memcpy_test(int channle_0, int channle_1) { |
| 333 | int i, err = 0, banks; |
| 334 | unsigned int addr, DDR_DMA0_SRC, DDR_DMA0_DST, DDR_DMA1_SRC, DDR_DMA1_DST; |
| 335 | volatile unsigned int tmp; |
| 336 | register unsigned int cpu_clk; |
| 337 | long int memsize, banksize, testsize; |
| 338 | int channel; |
| 339 | |
| 340 | #ifndef CONFIG_DDRC |
| 341 | banks = (SDRAM_BANK4 ? 4 : 2) *(CONFIG_NR_DRAM_BANKS); |
| 342 | #else |
| 343 | banks = (DDR_BANK8 ? 8 : 4) *(DDR_CS0EN + DDR_CS1EN); |
| 344 | #endif |
| 345 | memsize = initdram(0); |
| 346 | |
| 347 | banksize = memsize/banks; |
| 348 | testsize = 4096; |
| 349 | |
| 350 | DDR_DMA0_SRC = DDR_DMA_BASE + banksize*0; |
| 351 | DDR_DMA0_DST = DDR_DMA_BASE + banksize*0 + testsize; |
| 352 | DDR_DMA1_SRC = DDR_DMA_BASE + banksize*(banks - 1) + testsize*2; |
| 353 | DDR_DMA1_DST = DDR_DMA_BASE + banksize*(banks - 1) + testsize*3; |
| 354 | |
| 355 | cpu_clk = CFG_CPU_SPEED; |
| 356 | |
| 357 | // for(channel = 0; channel < MAX_DMA_NUM; channel++) { |
| 358 | |
| 359 | // MDMA |
| 360 | REG_MDMAC_DMACR = DMAC_DMACR_DMAE; |
| 361 | // COMMON DMA |
| 362 | //REG_DMAC_DMACR(0) = DMAC_DMACR_DMAE; /* global DMA enable bit */ |
| 363 | //REG_DMAC_DMACR(1) = DMAC_DMACR_DMAE; /* global DMA enable bit */ |
| 364 | |
| 365 | // Write A0 |
| 366 | addr = DDR_DMA0_SRC; |
| 367 | |
| 368 | for (i = 0; i < testsize; i += 4) { |
| 369 | *(volatile unsigned int *)addr = (i/4*0x11111111); |
| 370 | //*(volatile unsigned int *)addr = addr; |
| 371 | addr += 4; |
| 372 | } |
| 373 | |
| 374 | // Write A2 |
| 375 | addr = DDR_DMA1_SRC; |
| 376 | for (i = 0; i < testsize; i += 4) { |
| 377 | *(volatile unsigned int *)addr = (i/4*0x11111111); |
| 378 | //*(volatile unsigned int *)addr = addr; |
| 379 | addr += 4; |
| 380 | } |
| 381 | |
| 382 | |
| 383 | // MDMA |
| 384 | REG_MDMAC_DMACR = 0; |
| 385 | // COMMON DMA |
| 386 | //REG_DMAC_DMACR(0) = 0; |
| 387 | //REG_DMAC_DMACR(1) = 0; |
| 388 | |
| 389 | /* Init target buffer */ |
| 390 | jzmemset((void *)DDR_DMA0_DST, 0, testsize); |
| 391 | jzmemset((void *)DDR_DMA1_DST, 0, testsize); |
| 392 | |
| 393 | // Set DMA1 for moving data from A0 -> A1 |
| 394 | dma_data_move(channle_0, DDR_DMA0_SRC, DDR_DMA0_DST, testsize, DMAC_DCMD_DS_32BYTE); |
| 395 | // Set DMA2 for moving data from A2 -> A3 |
| 396 | dma_data_move(channle_1, DDR_DMA1_SRC, DDR_DMA1_DST, testsize, DMAC_DCMD_DS_64BYTE); |
| 397 | |
| 398 | // Start DMA0 |
| 399 | REG_DMAC_DCCSR(0) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; |
| 400 | // Wait for DMA0 finishing |
| 401 | while(REG_DMAC_DTCR(0)); |
| 402 | |
| 403 | // Start DMA1 |
| 404 | REG_DMAC_DCCSR(1) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; |
| 405 | |
| 406 | // Read from A1 & check |
| 407 | err = check_result((void *)DDR_DMA0_SRC, (void *)DDR_DMA0_DST, testsize); |
| 408 | REG_DMAC_DCCSR(0) &= ~DMAC_DCCSR_EN; /* disable DMA */ |
| 409 | if (err != 0) { |
| 410 | serial_puts("DMA0: err!\n"); |
| 411 | //return err; |
| 412 | } |
| 413 | |
| 414 | // Wait for DMA1 finishing |
| 415 | while(REG_DMAC_DTCR(1)); |
| 416 | |
| 417 | // Read from A3 & check |
| 418 | err = check_result((void *)DDR_DMA1_SRC, (void *)DDR_DMA1_DST, testsize); |
| 419 | REG_DMAC_DCCSR(1) &= ~DMAC_DCCSR_EN; /* disable DMA */ |
| 420 | if (err != 0) { |
| 421 | serial_puts("DMA1: err!\n"); |
| 422 | //return err; |
| 423 | } |
| 424 | |
| 425 | serial_puts("TEST PASSED\n\n"); |
| 426 | |
| 427 | tmp = (cpu_clk / 1000000) * 1; |
| 428 | while (tmp--); |
| 429 | // } |
| 430 | return err; |
| 431 | } |
| 432 | |
| 433 | #endif |
| 434 | |
| 435 | |
| 436 | void dma_nodesc_test(int dma_chan, int dma_src_addr, int dma_dst_addr, int size) |
| 437 | { |
| 438 | int dma_src_phys_addr, dma_dst_phys_addr; |
| 439 | |
| 440 | /* Allocate DMA buffers */ |
| 441 | dma_src_phys_addr = dma_src_addr & (~0xa0000000); |
| 442 | dma_dst_phys_addr = dma_dst_addr & (~0xa0000000); |
| 443 | |
| 444 | /* Init DMA module */ |
| 445 | REG_DMAC_DCCSR(dma_chan) = 0; |
| 446 | REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; |
| 447 | REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; |
| 448 | REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; |
| 449 | REG_DMAC_DTCR(dma_chan) = size / 32; |
| 450 | REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE; |
| 451 | REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; |
| 452 | } |
| 453 | |
| 454 | #define DDR_DMA_BASE (0xa0000000) /*un-cached*/ |
| 455 | #define DMA_CHANNEL0_EN |
| 456 | //#define DMA_CHANNEL1_EN |
| 457 | static int ddr_dma_test(int print_flag) { |
| 458 | int i, err = 0, banks; |
| 459 | int times; |
| 460 | unsigned int addr, DDR_DMA0_SRC, DDR_DMA0_DST, DDR_DMA1_SRC, DDR_DMA1_DST; |
| 461 | volatile unsigned int tmp; |
| 462 | register unsigned int cpu_clk; |
| 463 | long int memsize, banksize, testsize; |
| 464 | REG_DMAC_DMADCKE(0) = 0x3f; |
| 465 | REG_DMAC_DMADCKE(1) = 0x3f; |
| 466 | |
| 467 | #ifndef CONFIG_DDRC |
| 468 | banks = (SDRAM_BANK4 ? 4 : 2) *(CONFIG_NR_DRAM_BANKS); |
| 469 | #else |
| 470 | banks = (DDR_BANK8 ? 8 : 4) *(DDR_CS0EN + DDR_CS1EN); |
| 471 | #endif |
| 472 | memsize = initdram(0); |
| 473 | |
| 474 | banksize = memsize/banks; |
| 475 | testsize = 4096; |
| 476 | |
| 477 | for(times = 0; times < banks; times++) { |
| 478 | #if 0 |
| 479 | DDR_DMA0_SRC = DDR_DMA_BASE + banksize*0; |
| 480 | DDR_DMA0_DST = DDR_DMA_BASE + banksize*(banks - 2) + testsize; |
| 481 | DDR_DMA1_SRC = DDR_DMA_BASE + banksize*(banks - 1) + testsize; |
| 482 | DDR_DMA1_DST = DDR_DMA_BASE + banksize*1; |
| 483 | #else |
| 484 | DDR_DMA0_SRC = DDR_DMA_BASE + banksize*times; |
| 485 | DDR_DMA0_DST = DDR_DMA_BASE + banksize*(times+1) - testsize; |
| 486 | DDR_DMA1_SRC = DDR_DMA_BASE + banksize*(banks - 1) + testsize*2; |
| 487 | DDR_DMA1_DST = DDR_DMA_BASE + banksize*(banks - 1) + testsize*3; |
| 488 | #endif |
| 489 | |
| 490 | cpu_clk = CFG_CPU_SPEED; |
| 491 | |
| 492 | #ifdef DMA_CHANNEL0_EN |
| 493 | addr = DDR_DMA0_SRC; |
| 494 | |
| 495 | for (i = 0; i < testsize; i += 4) { |
| 496 | *(volatile unsigned int *)(addr + i) = gen_verify_data(i); |
| 497 | } |
| 498 | #endif |
| 499 | #ifdef DMA_CHANNEL1_EN |
| 500 | addr = DDR_DMA1_SRC; |
| 501 | for (i = 0; i < testsize; i += 4) { |
| 502 | |
| 503 | *(volatile unsigned int *)addr = gen_verify_data(i); |
| 504 | |
| 505 | addr += 4; |
| 506 | } |
| 507 | #endif |
| 508 | |
| 509 | REG_DMAC_DMACR(0) = 0; |
| 510 | // REG_DMAC_DMACR(1) = 0; |
| 511 | /* Init target buffer */ |
| 512 | #ifdef DMA_CHANNEL0_EN |
| 513 | jzmemset((void *)DDR_DMA0_DST, 0, testsize); |
| 514 | dma_nodesc_test(0, DDR_DMA0_SRC, DDR_DMA0_DST, testsize); |
| 515 | #endif |
| 516 | #ifdef DMA_CHANNEL1_EN |
| 517 | jzmemset((void *)DDR_DMA1_DST, 0, testsize); |
| 518 | dma_nodesc_test(1, DDR_DMA1_SRC, DDR_DMA1_DST, testsize); |
| 519 | #endif |
| 520 | |
| 521 | REG_DMAC_DMACR(0) = DMAC_DMACR_DMAE; /* global DMA enable bit */ |
| 522 | // REG_DMAC_DMACR(1) = DMAC_DMACR_DMAE; /* global DMA enable bit */ |
| 523 | // while(REG_DMAC_DTCR(0) || REG_DMAC_DTCR(1)); |
| 524 | while(REG_DMAC_DTCR(0)); |
| 525 | tmp = (cpu_clk / 1000000) * 1; |
| 526 | while (tmp--); |
| 527 | |
| 528 | #ifdef DMA_CHANNEL0_EN |
| 529 | err = dma_check_result((void *)DDR_DMA0_SRC, (void *)DDR_DMA0_DST, testsize,print_flag); |
| 530 | |
| 531 | REG_DMAC_DCCSR(0) &= ~DMAC_DCCSR_EN; /* disable DMA */ |
| 532 | |
| 533 | if(err == 0) { |
| 534 | serial_puts("passed:"); |
| 535 | serial_put_hex(times); |
| 536 | } else { |
| 537 | serial_put_hex(times); |
| 538 | } |
| 539 | |
| 540 | if (err != 0) { |
| 541 | #ifdef DMA_CHANNEL1_EN |
| 542 | REG_DMAC_DCCSR(1) &= ~DMAC_DCCSR_EN; /* disable DMA */ |
| 543 | #endif |
| 544 | return err; |
| 545 | } |
| 546 | |
| 547 | #endif |
| 548 | |
| 549 | #ifdef DMA_CHANNEL1_EN |
| 550 | //err += dma_check_result((void *)DDR_DMA1_SRC, (void *)DDR_DMA1_DST, testsize); |
| 551 | //REG_DMAC_DCCSR(1) &= ~DMAC_DCCSR_EN; /* disable DMA */ |
| 552 | #endif |
| 553 | } |
| 554 | return err; |
| 555 | } |
| 556 | |
| 557 | void ddr_mem_init(int msel, int hl, int tsel, int arg) |
| 558 | { |
| 559 | volatile int tmp_cnt; |
| 560 | register unsigned int cpu_clk, ddr_twr; |
| 561 | register unsigned int ddrc_cfg_reg=0, init_ddrc_mdelay=0; |
| 562 | |
| 563 | cpu_clk = CFG_CPU_SPEED; |
| 564 | |
| 565 | #if defined(CONFIG_SDRAM_DDR2) // ddr2 |
| 566 | ddrc_cfg_reg = DDRC_CFG_TYPE_DDR2 | (DDR_ROW-12)<<10 |
| 567 | | (DDR_COL-8)<<8 | DDR_CS1EN<<7 | DDR_CS0EN<<6 |
| 568 | | ((DDR_CL-1) | 0x8)<<2 | DDR_BANK8<<1 | DDR_DW32; |
| 569 | #elif defined(CONFIG_SDRAM_DDR1) // ddr1 |
| 570 | ddrc_cfg_reg = DDRC_CFG_BTRUN |DDRC_CFG_TYPE_DDR1 |
| 571 | | (DDR_ROW-12)<<10 | (DDR_COL-8)<<8 | DDR_CS1EN<<7 | DDR_CS0EN<<6 |
| 572 | | ((DDR_CL_HALF?(DDR_CL&~0x8):((DDR_CL-1)|0x8))<<2) |
| 573 | | DDR_BANK8<<1 | DDR_DW32; |
| 574 | #else // mobile ddr |
| 575 | ddrc_cfg_reg = DDRC_CFG_TYPE_MDDR |
| 576 | | (DDR_ROW-12)<<10 | (DDR_COL-8)<<8 | DDR_CS1EN<<7 | DDR_CS0EN<<6 |
| 577 | | ((DDR_CL-1) | 0x8)<<2 | DDR_BANK8<<1 | DDR_DW32; |
| 578 | #endif |
| 579 | |
| 580 | ddrc_cfg_reg |= DDRC_CFG_MPRT; |
| 581 | |
| 582 | #if defined(CONFIG_FPGA) |
| 583 | init_ddrc_mdelay= tsel<<18 | msel<<16 | hl<<15; |
| 584 | #else |
| 585 | init_ddrc_mdelay= tsel<<18 | msel<<16 | hl<<15 | arg << 14; |
| 586 | #endif |
| 587 | ddr_twr = ((REG_DDRC_TIMING1 & DDRC_TIMING1_TWR_MASK) >> DDRC_TIMING1_TWR_BIT) + 1; |
| 588 | REG_DDRC_CFG = ddrc_cfg_reg; |
| 589 | |
| 590 | REG_DDRC_MDELAY = init_ddrc_mdelay | 1 << 6; |
| 591 | /***** init ddrc registers & ddr memory regs ****/ |
| 592 | /* AR: auto refresh */ |
| 593 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 594 | /* Wait for DDR_tRP */ |
| 595 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 596 | while (tmp_cnt--); |
| 597 | |
| 598 | /* Wait for number of auto-refresh cycles */ |
| 599 | tmp_cnt = (cpu_clk / 1000000) * 10; |
| 600 | while (tmp_cnt--); |
| 601 | |
| 602 | #if defined(CONFIG_SDRAM_DDR2) // ddr1 and mddr |
| 603 | |
| 604 | /* Set CKE High */ |
| 605 | REG_DDRC_CTRL = DDRC_CTRL_CKE; // ? |
| 606 | |
| 607 | /* Wait for number of auto-refresh cycles */ |
| 608 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 609 | while (tmp_cnt--); |
| 610 | |
| 611 | /* PREA */ |
| 612 | REG_DDRC_LMR = DDRC_LMR_CMD_PREC | DDRC_LMR_START; //0x1; |
| 613 | |
| 614 | /* Wait for DDR_tRP */ |
| 615 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 616 | while (tmp_cnt--); |
| 617 | |
| 618 | /* EMR2: extend mode register2 */ |
| 619 | REG_DDRC_LMR = DDRC_LMR_BA_EMRS2 | DDRC_LMR_CMD_LMR | DDRC_LMR_START;//0x221; |
| 620 | |
| 621 | /* EMR3: extend mode register3 */ |
| 622 | REG_DDRC_LMR = DDRC_LMR_BA_EMRS3 | DDRC_LMR_CMD_LMR | DDRC_LMR_START;//0x321; |
| 623 | |
| 624 | /* EMR1: extend mode register1 */ |
| 625 | REG_DDRC_LMR = (DDR_EMRS1_DQS_DIS << 16) | DDRC_LMR_BA_EMRS1 | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 626 | |
| 627 | /* wait DDR_tMRD */ |
| 628 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 629 | while (tmp_cnt--); |
| 630 | |
| 631 | /* MR - DLL Reset A1A0 burst 2 */ |
| 632 | REG_DDRC_LMR = ((ddr_twr-1)<<9 | DDR2_MRS_DLL_RST | DDR_CL<<4 | DDR_MRS_BL_4)<< 16 |
| 633 | | DDRC_LMR_BA_MRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 634 | |
| 635 | /* wait DDR_tMRD */ |
| 636 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 637 | while (tmp_cnt--); |
| 638 | |
| 639 | /* PREA */ |
| 640 | REG_DDRC_LMR = DDRC_LMR_CMD_PREC | DDRC_LMR_START; //0x1; |
| 641 | |
| 642 | /* Wait for DDR_tRP */ |
| 643 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 644 | while (tmp_cnt--); |
| 645 | |
| 646 | /* AR: auto refresh */ |
| 647 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 648 | /* Wait for DDR_tRP */ |
| 649 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 650 | while (tmp_cnt--); |
| 651 | |
| 652 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 653 | |
| 654 | /* Wait for DDR_tRP */ |
| 655 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 656 | while (tmp_cnt--); |
| 657 | |
| 658 | /* MR - DLL Reset End */ |
| 659 | REG_DDRC_LMR = ((ddr_twr-1)<<9 | DDR_CL<<4 | DDR_MRS_BL_4)<< 16 |
| 660 | | DDRC_LMR_BA_MRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 661 | |
| 662 | /* wait 200 tCK */ |
| 663 | tmp_cnt = (cpu_clk / 1000000) * 2; |
| 664 | while (tmp_cnt--); |
| 665 | |
| 666 | /* EMR1 - OCD Default */ |
| 667 | REG_DDRC_LMR = (DDR_EMRS1_DQS_DIS | DDR_EMRS1_OCD_DFLT) << 16 |
| 668 | | DDRC_LMR_BA_EMRS1 | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 669 | |
| 670 | /* EMR1 - OCD Exit */ |
| 671 | REG_DDRC_LMR = (DDR_EMRS1_DQS_DIS << 16) | DDRC_LMR_BA_EMRS1 | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 672 | |
| 673 | /* wait DDR_tMRD */ |
| 674 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 675 | while (tmp_cnt--); |
| 676 | |
| 677 | #elif defined(CONFIG_SDRAM_DDR1) // ddr1 and mddr |
| 678 | /* set cke high */ |
| 679 | REG_DDRC_CTRL = DDRC_CTRL_CKE; // ? |
| 680 | |
| 681 | /* Nop command */ |
| 682 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 683 | while (tmp_cnt--); |
| 684 | |
| 685 | /* PREA all */ |
| 686 | // REG_DDRC_LMR = DDRC_LMR_CMD_PREC | DDRC_LMR_START; //0x1; |
| 687 | |
| 688 | /* Wait for DDR_tRP */ |
| 689 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 690 | while (tmp_cnt--); |
| 691 | |
| 692 | /* EMR: extend mode register: enable DLL */ |
| 693 | REG_DDRC_LMR = (DDR1_EMRS_OM_NORMAL | DDR1_EMRS_DS_FULL | DDR1_EMRS_DLL_EN) << 16 |
| 694 | | DDRC_LMR_BA_N_EMRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 695 | |
| 696 | /* MR DLL reset */ |
| 697 | REG_DDRC_LMR = (DDR1_MRS_OM_DLLRST | (DDR_CL_HALF?(DDR_CL|0x4):DDR_CL)<<4 | DDR_MRS_BL_4)<< 16 |
| 698 | | DDRC_LMR_BA_N_MRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 699 | |
| 700 | /* wait DDR_tXSRD, 200 tCK */ |
| 701 | tmp_cnt = (cpu_clk / 1000000) * 2; |
| 702 | while (tmp_cnt--); |
| 703 | /* PREA all */ |
| 704 | REG_DDRC_LMR = DDRC_LMR_CMD_PREC | DDRC_LMR_START; //0x1; |
| 705 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 706 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 707 | tmp_cnt = (cpu_clk / 1000000) * 15; |
| 708 | while (tmp_cnt--); |
| 709 | /* EMR: extend mode register, clear dll en */ |
| 710 | REG_DDRC_LMR = (DDR1_EMRS_OM_NORMAL | DDR1_EMRS_DS_FULL) << 16 |
| 711 | | DDRC_LMR_BA_N_EMRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 712 | /* wait DDR_tMRD */ |
| 713 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 714 | while (tmp_cnt--); |
| 715 | |
| 716 | #elif defined(CONFIG_SDRAM_MDDR) // ddr1 and mddr |
| 717 | REG_DDRC_CTRL = DDRC_CTRL_CKE; // ? |
| 718 | |
| 719 | /* Wait for number of auto-refresh cycles */ |
| 720 | tmp_cnt = (cpu_clk / 1000000) * 20; |
| 721 | while (tmp_cnt--); |
| 722 | |
| 723 | /* PREA */ |
| 724 | REG_DDRC_LMR = DDRC_LMR_CMD_PREC | DDRC_LMR_START; //0x1; |
| 725 | |
| 726 | /* Wait for DDR_tRP */ |
| 727 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 728 | while (tmp_cnt--); |
| 729 | |
| 730 | /* AR: auto refresh */ |
| 731 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 732 | |
| 733 | /* wait DDR_tRFC */ |
| 734 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 735 | while (tmp_cnt--); |
| 736 | |
| 737 | /* AR: auto refresh */ |
| 738 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 739 | /* wait DDR_tRFC */ |
| 740 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 741 | while (tmp_cnt--); |
| 742 | |
| 743 | /* MR */ |
| 744 | REG_DDRC_LMR = (DDR_CL<<4 | DDR_MRS_BL_4)<< 16 |
| 745 | | DDRC_LMR_BA_M_MRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 746 | |
| 747 | /* wait DDR_tMRD */ |
| 748 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 749 | while (tmp_cnt--); |
| 750 | |
| 751 | /* EMR: extend mode register */ |
| 752 | REG_DDRC_LMR = (DDR_EMRS_DS_HALF | DDR_EMRS_PRSR_ALL) << 16 |
| 753 | | DDRC_LMR_BA_M_EMRS | DDRC_LMR_CMD_LMR | DDRC_LMR_START; |
| 754 | |
| 755 | /* wait DDR_tMRD */ |
| 756 | tmp_cnt = (cpu_clk / 1000000) * 1; |
| 757 | while (tmp_cnt--); |
| 758 | |
| 759 | #endif |
| 760 | } |
| 761 | void testallmem() |
| 762 | { |
| 763 | unsigned int i,d; |
| 764 | unsigned int *dat; |
| 765 | dat = (unsigned int *)0xa0000000; |
| 766 | for(i = 0; i < 64*1024*1024;i+=4) |
| 767 | { |
| 768 | *dat = i; |
| 769 | dat++; |
| 770 | } |
| 771 | |
| 772 | dat = (unsigned int *)0xa0000000; |
| 773 | for(i = 0; i < 64*1024*1024;i+=4) |
| 774 | { |
| 775 | d = *dat; |
| 776 | if(d != i) |
| 777 | { |
| 778 | serial_puts("errdata:\n"); |
| 779 | serial_puts("expect:\n"); |
| 780 | serial_put_hex(i); |
| 781 | serial_put_hex(d); |
| 782 | } |
| 783 | dat++; |
| 784 | } |
| 785 | |
| 786 | } |
| 787 | |
| 788 | #define DDR_DMA_BASE (0xa0000000) /*un-cached*/ |
| 789 | |
| 790 | void dma_data_move(int dma_chan, int dma_src_addr, int dma_dst_addr, int size, int burst) |
| 791 | { |
| 792 | int dma_src_phys_addr, dma_dst_phys_addr; |
| 793 | |
| 794 | /* set addr to uncached */ |
| 795 | dma_src_phys_addr = dma_src_addr & ~0xa0000000; |
| 796 | dma_dst_phys_addr = dma_dst_addr & ~0xa0000000; |
| 797 | |
| 798 | /* Init DMA module */ |
| 799 | |
| 800 | REG_DMAC_DCCSR(dma_chan) = 0; |
| 801 | REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; |
| 802 | REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; |
| 803 | REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; |
| 804 | REG_DMAC_DTCR(dma_chan) = size / 32; |
| 805 | REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | burst; |
| 806 | // REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; |
| 807 | } |
| 808 | |
| 809 | static int check_result(void *src, void *dst, int size) |
| 810 | { |
| 811 | unsigned int addr1, addr2, i, err = 0; |
| 812 | |
| 813 | addr1 = (unsigned int)src; |
| 814 | addr2 = (unsigned int)dst; |
| 815 | |
| 816 | for (i = 0; i < size; i += 4) { |
| 817 | if ((*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) |
| 818 | || (*(volatile unsigned int *)addr1 != (i/4*0x11111111))) { |
| 819 | #ifdef DEBUG |
| 820 | err++; |
| 821 | if (err < 10){ |
| 822 | serial_puts("wrong data at");serial_put_hex(addr2); |
| 823 | serial_puts("data");serial_put_hex(i/4*0x11111111); |
| 824 | serial_puts("src");serial_put_hex(*(volatile unsigned int *)addr1); |
| 825 | serial_puts("dst");serial_put_hex(*(volatile unsigned int *)addr2); |
| 826 | } |
| 827 | #else |
| 828 | return 1; |
| 829 | #endif |
| 830 | } |
| 831 | |
| 832 | addr1 += 4; |
| 833 | addr2 += 4; |
| 834 | } |
| 835 | return err; |
| 836 | } |
| 837 | |
| 838 | #endif |
| 839 | |
| 840 | #if (defined(CONFIG_SDRAM_MDDR) || defined(CONFIG_SDRAM_DDR1) || defined(CONFIG_SDRAM_DDR2)) |
| 841 | #define DEF_DDR_CVT 0 |
| 842 | #define DDR_USE_FIRST_ARGS 0 |
| 843 | unsigned int testall = 0; |
| 844 | /* DDR sdram init */ |
| 845 | void sdram_init_4760(void) |
| 846 | { |
| 847 | //add driver power |
| 848 | REG_EMC_PMEMPS2 |= (3 << 18); |
| 849 | |
| 850 | REG_DMAC_DMADCKE(0) = 0x3f; |
| 851 | REG_DMAC_DMADCKE(1) = 0x3f; |
| 852 | int i, num = 0, tsel = 0, msel, hl; |
| 853 | volatile unsigned int tmp_cnt; |
| 854 | register unsigned int tmp, cpu_clk, mem_clk, ddr_twr, ns, ns_int; |
| 855 | register unsigned int ddrc_timing1_reg=0, ddrc_timing2_reg=0; |
| 856 | register unsigned int init_ddrc_refcnt=0, init_ddrc_dqs=0, init_ddrc_ctrl=0; |
| 857 | |
| 858 | register unsigned int memsize, ddrc_mmap0_reg, ddrc_mmap1_reg; |
| 859 | register unsigned int mem_base0, mem_base1, mem_mask0, mem_mask1; |
| 860 | |
| 861 | #if defined(CONFIG_FPGA) |
| 862 | int cvt = DEF_DDR_CVT, cvt_cnt0 = 0, cvt_cnt1 = 1; |
| 863 | int max = 0, max0 = 0, max1 = 0, min0 = 0, min1 = 0; |
| 864 | int tsel0 = 0, tsel1 = 0; |
| 865 | struct ddr_delay_sel_t ddr_delay_sel[] = { |
| 866 | {0, 1}, {0, 0}, {1, 1}, {1, 0}, |
| 867 | {2, 1}, {2, 0}, {3, 1}, {3, 0} |
| 868 | }; |
| 869 | #endif |
| 870 | |
| 871 | testall = 0; |
| 872 | cpu_clk = CFG_CPU_SPEED; |
| 873 | |
| 874 | #ifdef DEBUG |
| 875 | ddrc_regs_print(); |
| 876 | #endif |
| 877 | |
| 878 | #if defined(CONFIG_FPGA) |
| 879 | mem_clk = CFG_EXTAL / CFG_DIV; |
| 880 | ns = 7; |
| 881 | #else |
| 882 | mem_clk = __cpm_get_mclk(); |
| 883 | ns = 1000000000 / mem_clk; /* ns per tck ns <= real value */ |
| 884 | #endif |
| 885 | |
| 886 | #ifdef DEBUG |
| 887 | serial_puts("mem_clk = "); |
| 888 | serial_put_hex(mem_clk); |
| 889 | #endif |
| 890 | |
| 891 | /* ACTIVE to PRECHARGE command period */ |
| 892 | tmp = (DDR_tRAS%ns == 0) ? (DDR_tRAS/ns) : (DDR_tRAS/ns+1); |
| 893 | if (tmp < 1) tmp = 1; |
| 894 | if (tmp > 31) tmp = 31; |
| 895 | ddrc_timing1_reg = ((tmp/2) << DDRC_TIMING1_TRAS_BIT); |
| 896 | |
| 897 | /* READ to PRECHARGE command period. */ |
| 898 | tmp = (DDR_tRTP%ns == 0) ? (DDR_tRTP/ns) : (DDR_tRTP/ns+1); |
| 899 | if (tmp < 1) tmp = 1; |
| 900 | if (tmp > 4) tmp = 4; |
| 901 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TRTP_BIT); |
| 902 | |
| 903 | /* PRECHARGE command period. */ |
| 904 | tmp = (DDR_tRP%ns == 0) ? DDR_tRP/ns : (DDR_tRP/ns+1); |
| 905 | if (tmp < 1) tmp = 1; |
| 906 | if (tmp > 8) tmp = 8; |
| 907 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TRP_BIT); |
| 908 | |
| 909 | /* ACTIVE to READ or WRITE command period. */ |
| 910 | tmp = (DDR_tRCD%ns == 0) ? DDR_tRCD/ns : (DDR_tRCD/ns+1); |
| 911 | if (tmp < 1) tmp = 1; |
| 912 | if (tmp > 8) tmp = 8; |
| 913 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TRCD_BIT); |
| 914 | |
| 915 | /* ACTIVE to ACTIVE command period. */ |
| 916 | tmp = (DDR_tRC%ns == 0) ? DDR_tRC/ns : (DDR_tRC/ns+1); |
| 917 | if (tmp < 3) tmp = 3; |
| 918 | if (tmp > 31) tmp = 31; |
| 919 | ddrc_timing1_reg |= ((tmp/2) << DDRC_TIMING1_TRC_BIT); |
| 920 | |
| 921 | /* ACTIVE bank A to ACTIVE bank B command period. */ |
| 922 | tmp = (DDR_tRRD%ns == 0) ? DDR_tRRD/ns : (DDR_tRRD/ns+1); |
| 923 | if (tmp < 2) tmp = 2; |
| 924 | if (tmp > 4) tmp = 4; |
| 925 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TRRD_BIT); |
| 926 | |
| 927 | |
| 928 | /* WRITE Recovery Time defined by register MR of DDR2 memory */ |
| 929 | tmp = (DDR_tWR%ns == 0) ? DDR_tWR/ns : (DDR_tWR/ns+1); |
| 930 | tmp = (tmp < 1) ? 1 : tmp; |
| 931 | tmp = (tmp < 2) ? 2 : tmp; |
| 932 | tmp = (tmp > 6) ? 6 : tmp; |
| 933 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TWR_BIT); |
| 934 | ddr_twr = tmp; |
| 935 | |
| 936 | /* WRITE to READ command delay. */ |
| 937 | tmp = (DDR_tWTR%ns == 0) ? DDR_tWTR/ns : (DDR_tWTR/ns+1); |
| 938 | if (tmp > 4) tmp = 4; |
| 939 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TWTR_BIT); |
| 940 | |
| 941 | |
| 942 | /* WRITE to READ command delay. */ |
| 943 | tmp = DDR_tWTR/ns; |
| 944 | if (tmp < 1) tmp = 1; |
| 945 | if (tmp > 4) tmp = 4; |
| 946 | ddrc_timing1_reg |= ((tmp-1) << DDRC_TIMING1_TWTR_BIT); |
| 947 | |
| 948 | /* AUTO-REFRESH command period. */ |
| 949 | tmp = (DDR_tRFC%ns == 0) ? DDR_tRFC/ns : (DDR_tRFC/ns+1); |
| 950 | if (tmp > 31) tmp = 31; |
| 951 | ddrc_timing2_reg = ((tmp/2) << DDRC_TIMING2_TRFC_BIT); |
| 952 | |
| 953 | /* Minimum Self-Refresh / Deep-Power-Down time */ |
| 954 | tmp = DDR_tMINSR/ns; |
| 955 | if (tmp < 9) tmp = 9; |
| 956 | if (tmp > 129) tmp = 129; |
| 957 | ddrc_timing2_reg |= (((tmp-1)/8-1) << DDRC_TIMING2_TMINSR_BIT); |
| 958 | ddrc_timing2_reg |= (DDR_tXP-1)<<4 | (DDR_tMRD-1); |
| 959 | |
| 960 | init_ddrc_refcnt = DDR_CLK_DIV << 1 | DDRC_REFCNT_REF_EN; |
| 961 | |
| 962 | ns_int = (1000000000%mem_clk == 0) ? |
| 963 | (1000000000/mem_clk) : (1000000000/mem_clk+1); |
| 964 | tmp = DDR_tREFI/ns_int; |
| 965 | tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1; |
| 966 | if (tmp > 0xfff) |
| 967 | tmp = 0xfff; |
| 968 | if (tmp < 1) |
| 969 | tmp = 1; |
| 970 | |
| 971 | init_ddrc_refcnt |= tmp << DDRC_REFCNT_CON_BIT; |
| 972 | init_ddrc_dqs = DDRC_DQS_AUTO | DDRC_DQS_DET; |
| 973 | |
| 974 | /* precharge power down, disable power down */ |
| 975 | /* precharge power down, if set active power down, |= DDRC_CTRL_ACTPD */ |
| 976 | init_ddrc_ctrl = DDRC_CTRL_PDT_DIS | DDRC_CTRL_PRET_8 | DDRC_CTRL_UNALIGN | DDRC_CTRL_CKE; |
| 977 | /* Add Jz4760 chip here. Jz4760 chip have no cvt */ |
| 978 | #define MAX_TSEL_VALUE 4 |
| 979 | #define MAX_DELAY_VALUES 16 /* quars (2) * hls (2) * msels (4) */ |
| 980 | int j, index, quar; |
| 981 | int mem_index[MAX_DELAY_VALUES]; |
| 982 | #if 0 // probe |
| 983 | jzmemset(mem_index, 0, MAX_DELAY_VALUES); |
| 984 | for (i = 1; i < MAX_TSEL_VALUE; i ++) { |
| 985 | tsel = i; |
| 986 | for (j = 0; j < MAX_DELAY_VALUES; j++) { |
| 987 | msel = j/4; |
| 988 | hl = ((j/2)&1)^1; |
| 989 | quar = j&1; |
| 990 | |
| 991 | /* reset ddrc_controller */ |
| 992 | REG_DDRC_CTRL = DDRC_CTRL_RESET; |
| 993 | |
| 994 | /* Wait for precharge, > 200us */ |
| 995 | tmp_cnt = (cpu_clk / 1000000) * 200; |
| 996 | while (tmp_cnt--); |
| 997 | |
| 998 | REG_DDRC_CTRL = 0x0; |
| 999 | REG_DDRC_TIMING1 = ddrc_timing1_reg; |
| 1000 | REG_DDRC_TIMING2 = ddrc_timing2_reg; |
| 1001 | |
| 1002 | ddr_mem_init(msel, hl, tsel, quar); |
| 1003 | |
| 1004 | memsize = initdram(0); |
| 1005 | mem_base0 = DDR_MEM_PHY_BASE >> 24; |
| 1006 | mem_base1 = (DDR_MEM_PHY_BASE + memsize / (DDR_CS1EN + DDR_CS0EN)) >> 24; |
| 1007 | mem_mask1 = mem_mask0 = 0xff & |
| 1008 | ~(((memsize/(DDR_CS1EN+DDR_CS0EN) >> 24) |
| 1009 | - 1) & DDRC_MMAP_MASK_MASK); |
| 1010 | |
| 1011 | ddrc_mmap0_reg = mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0; |
| 1012 | ddrc_mmap1_reg = mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1; |
| 1013 | |
| 1014 | REG_DDRC_MMAP0 = ddrc_mmap0_reg; |
| 1015 | REG_DDRC_MMAP1 = ddrc_mmap1_reg; |
| 1016 | |
| 1017 | REG_DDRC_REFCNT = init_ddrc_refcnt; |
| 1018 | |
| 1019 | /* Enable DLL Detect */ |
| 1020 | REG_DDRC_DQS = init_ddrc_dqs; |
| 1021 | |
| 1022 | while(!(REG_DDRC_DQS &( DDRC_DQS_ERROR | DDRC_DQS_READY))); |
| 1023 | /* Set CKE High */ |
| 1024 | REG_DDRC_CTRL = init_ddrc_ctrl; |
| 1025 | |
| 1026 | /* Wait for number of auto-refresh cycles */ |
| 1027 | tmp_cnt = (cpu_clk / 1000000) * 10; |
| 1028 | while (tmp_cnt--); |
| 1029 | |
| 1030 | /* Auto Refresh */ |
| 1031 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 1032 | |
| 1033 | /* Wait for number of auto-refresh cycles */ |
| 1034 | tmp_cnt = (cpu_clk / 1000000) * 10; |
| 1035 | while (tmp_cnt--); |
| 1036 | |
| 1037 | tmp_cnt = (cpu_clk / 1000000) * 10; |
| 1038 | while (tmp_cnt--); |
| 1039 | |
| 1040 | { |
| 1041 | int result = 0; |
| 1042 | result = ddr_dma_test(0); |
| 1043 | if(result != 0) |
| 1044 | serial_puts("FAIL!\n"); |
| 1045 | #if DEBUG |
| 1046 | serial_puts("result:"); |
| 1047 | serial_put_hex(result); |
| 1048 | serial_put_hex(num); |
| 1049 | #endif |
| 1050 | |
| 1051 | if(result != 0) { |
| 1052 | if (num > 0) |
| 1053 | break; |
| 1054 | else |
| 1055 | continue; |
| 1056 | } else { /* test pass */ |
| 1057 | |
| 1058 | mem_index[num] = j; |
| 1059 | num++; |
| 1060 | } |
| 1061 | } |
| 1062 | } |
| 1063 | |
| 1064 | if (num > 0) |
| 1065 | break; |
| 1066 | } |
| 1067 | if (tsel == 3 && num == 0) |
| 1068 | serial_puts("DDR INIT ERROR\n"); /* can't find a suitable mask delay. */ |
| 1069 | index = 0; |
| 1070 | for (i = 0; i < num; i++) { |
| 1071 | index += mem_index[i]; |
| 1072 | serial_put_hex(mem_index[i]); |
| 1073 | } |
| 1074 | |
| 1075 | #ifdef DEBUG |
| 1076 | serial_puts("index-1:"); |
| 1077 | serial_put_hex(index); |
| 1078 | #endif |
| 1079 | |
| 1080 | if (num) |
| 1081 | index /= num; |
| 1082 | #endif |
| 1083 | |
| 1084 | msel = index/4; |
| 1085 | hl = ((index/2)&1)^1; |
| 1086 | quar = index&1; |
| 1087 | |
| 1088 | #ifdef DEBUG |
| 1089 | serial_puts("tsel"); |
| 1090 | serial_put_hex(tsel); |
| 1091 | serial_puts("num"); |
| 1092 | serial_put_hex(num); |
| 1093 | serial_puts("index-2:"); |
| 1094 | serial_put_hex(index); |
| 1095 | #endif |
| 1096 | |
| 1097 | /* reset ddrc_controller */ |
| 1098 | REG_DDRC_CTRL = DDRC_CTRL_RESET; |
| 1099 | |
| 1100 | /* Wait for precharge, > 200us */ |
| 1101 | tmp_cnt = (cpu_clk / 1000000) * 200; |
| 1102 | while (tmp_cnt--); |
| 1103 | |
| 1104 | REG_DDRC_CTRL = 0x0; |
| 1105 | REG_DDRC_TIMING1 = ddrc_timing1_reg; |
| 1106 | REG_DDRC_TIMING2 = ddrc_timing2_reg; |
| 1107 | |
| 1108 | ddr_mem_init(msel, hl, tsel, quar); |
| 1109 | |
| 1110 | memsize = initdram(0); |
| 1111 | mem_base0 = DDR_MEM_PHY_BASE >> 24; |
| 1112 | mem_base1 = (DDR_MEM_PHY_BASE + memsize / (DDR_CS1EN + DDR_CS0EN)) >> 24; |
| 1113 | mem_mask1 = mem_mask0 = 0xff & |
| 1114 | ~(((memsize/(DDR_CS1EN+DDR_CS0EN) >> 24) |
| 1115 | - 1) & DDRC_MMAP_MASK_MASK); |
| 1116 | |
| 1117 | ddrc_mmap0_reg = mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0; |
| 1118 | ddrc_mmap1_reg = mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1; |
| 1119 | |
| 1120 | REG_DDRC_MMAP0 = ddrc_mmap0_reg; |
| 1121 | REG_DDRC_MMAP1 = ddrc_mmap1_reg; |
| 1122 | REG_DDRC_REFCNT = init_ddrc_refcnt; |
| 1123 | |
| 1124 | /* Enable DLL Detect */ |
| 1125 | REG_DDRC_DQS = init_ddrc_dqs; |
| 1126 | |
| 1127 | /* Set CKE High */ |
| 1128 | REG_DDRC_CTRL = init_ddrc_ctrl; |
| 1129 | |
| 1130 | /* Wait for number of auto-refresh cycles */ |
| 1131 | tmp_cnt = (cpu_clk / 1000000) * 10; |
| 1132 | while (tmp_cnt--); |
| 1133 | |
| 1134 | /* Auto Refresh */ |
| 1135 | REG_DDRC_LMR = DDRC_LMR_CMD_AUREF | DDRC_LMR_START; //0x11; |
| 1136 | |
| 1137 | /* Wait for number of auto-refresh cycles */ |
| 1138 | tmp_cnt = (cpu_clk / 1000000) * 10; |
| 1139 | while (tmp_cnt--); |
| 1140 | if(testall) |
| 1141 | testallmem(); |
| 1142 | } |
| 1143 | #else |
| 1144 | void sdram_init_4760(void) |
| 1145 | { |
| 1146 | register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; |
| 1147 | |
| 1148 | unsigned int cas_latency_sdmr[2] = { |
| 1149 | EMC_SDMR_CAS_2, |
| 1150 | EMC_SDMR_CAS_3, |
| 1151 | }; |
| 1152 | |
| 1153 | unsigned int cas_latency_dmcr[2] = { |
| 1154 | 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */ |
| 1155 | 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ |
| 1156 | }; |
| 1157 | |
| 1158 | int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; |
| 1159 | |
| 1160 | cpu_clk = CFG_CPU_SPEED; |
| 1161 | mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; |
| 1162 | |
| 1163 | REG_EMC_BCR = 0; /* Disable bus release */ |
| 1164 | REG_EMC_RTCSR = 0; /* Disable clock for counting */ |
| 1165 | |
| 1166 | /* Fault DMCR value for mode register setting*/ |
| 1167 | #define SDRAM_ROW0 11 |
| 1168 | #define SDRAM_COL0 8 |
| 1169 | #define SDRAM_BANK40 0 |
| 1170 | |
| 1171 | dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) | |
| 1172 | ((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) | |
| 1173 | (SDRAM_BANK40<<EMC_DMCR_BA_BIT) | |
| 1174 | (SDRAM_BW16<<EMC_DMCR_BW_BIT) | |
| 1175 | EMC_DMCR_EPIN | |
| 1176 | cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; |
| 1177 | |
| 1178 | /* Basic DMCR value */ |
| 1179 | dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) | |
| 1180 | ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) | |
| 1181 | (SDRAM_BANK4<<EMC_DMCR_BA_BIT) | |
| 1182 | (SDRAM_BW16<<EMC_DMCR_BW_BIT) | |
| 1183 | EMC_DMCR_EPIN | |
| 1184 | cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; |
| 1185 | |
| 1186 | /* SDRAM timimg */ |
| 1187 | ns = 1000000000 / mem_clk; |
| 1188 | tmp = SDRAM_TRAS/ns; |
| 1189 | if (tmp < 4) tmp = 4; |
| 1190 | if (tmp > 11) tmp = 11; |
| 1191 | dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT); |
| 1192 | tmp = SDRAM_RCD/ns; |
| 1193 | if (tmp > 3) tmp = 3; |
| 1194 | dmcr |= (tmp << EMC_DMCR_RCD_BIT); |
| 1195 | tmp = SDRAM_TPC/ns; |
| 1196 | if (tmp > 7) tmp = 7; |
| 1197 | dmcr |= (tmp << EMC_DMCR_TPC_BIT); |
| 1198 | tmp = SDRAM_TRWL/ns; |
| 1199 | if (tmp > 3) tmp = 3; |
| 1200 | dmcr |= (tmp << EMC_DMCR_TRWL_BIT); |
| 1201 | tmp = (SDRAM_TRAS + SDRAM_TPC)/ns; |
| 1202 | if (tmp > 14) tmp = 14; |
| 1203 | dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT); |
| 1204 | |
| 1205 | /* SDRAM mode value */ |
| 1206 | sdmode = EMC_SDMR_BT_SEQ | |
| 1207 | EMC_SDMR_OM_NORMAL | |
| 1208 | EMC_SDMR_BL_4 | |
| 1209 | cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; |
| 1210 | |
| 1211 | /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ |
| 1212 | REG_EMC_DMCR = dmcr; |
| 1213 | REG8(EMC_SDMR0|sdmode) = 0; |
| 1214 | |
| 1215 | /* Wait for precharge, > 200us */ |
| 1216 | tmp = (cpu_clk / 1000000) * 1000; |
| 1217 | while (tmp--); |
| 1218 | |
| 1219 | /* Stage 2. Enable auto-refresh */ |
| 1220 | REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH; |
| 1221 | |
| 1222 | tmp = SDRAM_TREF/ns; |
| 1223 | tmp = tmp/64 + 1; |
| 1224 | if (tmp > 0xff) tmp = 0xff; |
| 1225 | REG_EMC_RTCOR = tmp; |
| 1226 | REG_EMC_RTCNT = 0; |
| 1227 | REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ |
| 1228 | |
| 1229 | /* Wait for number of auto-refresh cycles */ |
| 1230 | tmp = (cpu_clk / 1000000) * 1000; |
| 1231 | while (tmp--); |
| 1232 | |
| 1233 | /* Stage 3. Mode Register Set */ |
| 1234 | REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; |
| 1235 | REG8(EMC_SDMR0|sdmode) = 0; |
| 1236 | |
| 1237 | /* Set back to basic DMCR value */ |
| 1238 | REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; |
| 1239 | |
| 1240 | /* everything is ok now */ |
| 1241 | } |
| 1242 | #endif |
| 1243 | |
| 1244 | static void serial_setbrg(void) |
| 1245 | { |
| 1246 | volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); |
| 1247 | volatile u8 *uart_dlhr = (volatile u8 *)(UART_BASE + OFF_DLHR); |
| 1248 | volatile u8 *uart_dllr = (volatile u8 *)(UART_BASE + OFF_DLLR); |
| 1249 | u32 baud_div, tmp; |
| 1250 | |
| 1251 | baud_div = (CFG_EXTAL / 16 / 57600); |
| 1252 | tmp = *uart_lcr; |
| 1253 | tmp |= UART_LCR_DLAB; |
| 1254 | *uart_lcr = tmp; |
| 1255 | |
| 1256 | *uart_dlhr = (baud_div >> 8) & 0xff; |
| 1257 | *uart_dllr = baud_div & 0xff; |
| 1258 | |
| 1259 | tmp &= ~UART_LCR_DLAB; |
| 1260 | *uart_lcr = tmp; |
| 1261 | } |
| 1262 | |
| 1263 | void serial_init_4760(int uart) |
| 1264 | { |
| 1265 | UART_BASE = UART0_BASE + uart * UART_OFF; |
| 1266 | |
| 1267 | volatile u8 *uart_fcr = (volatile u8 *)(UART_BASE + OFF_FCR); |
| 1268 | volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); |
| 1269 | volatile u8 *uart_ier = (volatile u8 *)(UART_BASE + OFF_IER); |
| 1270 | volatile u8 *uart_sircr = (volatile u8 *)(UART_BASE + OFF_SIRCR); |
| 1271 | |
| 1272 | /* Disable port interrupts while changing hardware */ |
| 1273 | *uart_ier = 0; |
| 1274 | |
| 1275 | /* Disable UART unit function */ |
| 1276 | *uart_fcr = ~UART_FCR_UUE; |
| 1277 | |
| 1278 | /* Set both receiver and transmitter in UART mode (not SIR) */ |
| 1279 | *uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE); |
| 1280 | |
| 1281 | /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ |
| 1282 | *uart_lcr = UART_LCR_WLEN_8 | UART_LCR_STOP_1; |
| 1283 | |
| 1284 | /* Set baud rate */ |
| 1285 | serial_setbrg(); |
| 1286 | |
| 1287 | /* Enable UART unit, enable and clear FIFO */ |
| 1288 | *uart_fcr = UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS; |
| 1289 | } |
| 1290 | |