Christophe Leroy | 1fc46f5 | 2022-10-14 12:54:50 +0200 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Copyright (C) 2020 CS Group |
| 4 | * Charles Frey <charles.frey@c-s.fr> |
| 5 | */ |
| 6 | |
| 7 | #include <common.h> |
| 8 | #include <linux/sizes.h> |
| 9 | #include <linux/delay.h> |
| 10 | #include <init.h> |
| 11 | #include <asm/io.h> |
| 12 | #include <mpc8xx.h> |
| 13 | #include <watchdog.h> |
| 14 | |
| 15 | DECLARE_GLOBAL_DATA_PTR; |
| 16 | |
| 17 | #define ADDR_CPLD_R_TYPE ((unsigned char __iomem *)CONFIG_CPLD_BASE + 3) |
| 18 | |
| 19 | #define _NOT_USED_ 0xFFFFEC04 |
| 20 | |
| 21 | static const uint sdram_table[] = { |
| 22 | /* DRAM - single read. (offset 0 in upm RAM) */ |
| 23 | 0x0F0CEC04, 0x0FFFEC04, 0x00AF2C04, 0x0FFFEC00, |
| 24 | 0x0FFCE004, 0xFFFFEC05, _NOT_USED_, _NOT_USED_, |
| 25 | |
| 26 | /* DRAM - burst read. (offset 8 in upm RAM) */ |
| 27 | 0x0F0CEC04, 0x0FFFEC04, 0x00AF2C04, 0x00FFEC00, |
| 28 | 0x00FFEC00, 0x00FFEC00, 0x0FFCE000, 0x1FFFEC05, |
| 29 | |
| 30 | /* DRAM - Precharge all banks. (offset 16 in upm RAM) */ |
| 31 | _NOT_USED_, 0x0FFCE004, 0x1FFFEC05, _NOT_USED_, |
| 32 | |
| 33 | /* DRAM - NOP. (offset 20 in upm RAM) */ |
| 34 | 0x1FFFEC05, _NOT_USED_, _NOT_USED_, _NOT_USED_, |
| 35 | |
| 36 | /* DRAM - single write. (offset 24 in upm RAM) */ |
| 37 | 0x0F0CEC04, 0x0FFFEC00, 0x00AF2004, 0x0FFFEC04, |
| 38 | 0x0FFCE004, 0x0FFFEC04, 0xFFFFEC05, _NOT_USED_, |
| 39 | |
| 40 | /* DRAM - burst write. (offset 32 in upm RAM) */ |
| 41 | 0x0F0CEC04, 0x0FFFEC00, 0x00AF2000, 0x00FFEC00, |
| 42 | 0x00FFEC00, 0x00FFEC04, 0x0FFFEC04, 0x0FFCE004, |
| 43 | 0x1FFFEC05, _NOT_USED_, _NOT_USED_, _NOT_USED_, |
| 44 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, |
| 45 | |
| 46 | /* refresh (offset 48 in upm RAM) */ |
| 47 | 0x0FFDE404, 0x0FFEAC04, 0x0FFD6C84, 0x0FFFEC04, |
| 48 | 0x0FFFEC04, 0x0FFFEC04, 0x0FFFEC04, 0x1FFFEC85, |
| 49 | |
| 50 | /* init (offset 56 in upm RAM) */ |
| 51 | 0x0FEEA874, 0x0FBD6474, 0x1FFFEC45, _NOT_USED_, |
| 52 | |
| 53 | /* exception. (offset 60 in upm RAM) */ |
| 54 | 0x0FFCE004, 0xFFFFEC05, _NOT_USED_, _NOT_USED_ |
| 55 | }; |
| 56 | |
| 57 | /* SDRAM initialization */ |
| 58 | int dram_init(void) |
| 59 | { |
| 60 | immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; |
| 61 | memctl8xx_t __iomem *memctl = &immap->im_memctl; |
| 62 | u32 max_size, mamr; |
| 63 | u8 val; |
| 64 | |
| 65 | printf("UPMA init for SDRAM (CAS latency 2), "); |
| 66 | printf("init address 0x%08x, size ", (int)dram_init); |
| 67 | |
| 68 | /* Verify the SDRAM size of the board */ |
| 69 | val = (in_8(ADDR_CPLD_R_TYPE) & 0x30) >> 4; |
| 70 | |
| 71 | if (val == 0x03 || val == 0x00) { |
| 72 | max_size = 64 * SZ_1M; /* 64 Mo of SDRAM */ |
| 73 | mamr = 0x20104000; |
| 74 | } else { |
| 75 | max_size = 128 * SZ_1M; /* 128 Mo of SDRAM */ |
| 76 | mamr = 0x20206000; |
| 77 | } |
| 78 | |
| 79 | /* Configure CS1 */ |
| 80 | out_be32(&memctl->memc_or1, |
| 81 | ~(max_size - 1) | OR_CSNT_SAM | OR_ACS_DIV2); |
| 82 | out_be32(&memctl->memc_br1, CFG_SYS_SDRAM_BASE | BR_MS_UPMA | BR_V); |
| 83 | |
| 84 | /* Configure UPMA for CS1 */ |
| 85 | upmconfig(UPMA, (uint *)sdram_table, ARRAY_SIZE(sdram_table)); |
| 86 | |
| 87 | out_be16(&memctl->memc_mptpr, MPTPR_PTP_DIV32); |
| 88 | /* disable refresh */ |
| 89 | out_be32(&memctl->memc_mamr, mamr); |
| 90 | udelay(100); |
| 91 | |
| 92 | /* NOP to maintain DQM high */ |
| 93 | out_be32(&memctl->memc_mcr, 0x80002114); |
| 94 | udelay(200); |
| 95 | |
| 96 | out_be32(&memctl->memc_mcr, 0x80002111); /* PRECHARGE cmd */ |
| 97 | out_be32(&memctl->memc_mcr, 0x80002830); /* AUTO REFRESH cmd */ |
| 98 | out_be32(&memctl->memc_mar, 0x00000088); |
| 99 | out_be32(&memctl->memc_mcr, 0x80002138); |
| 100 | |
| 101 | /* Enable refresh */ |
| 102 | setbits_be32(&memctl->memc_mamr, MAMR_PTAE); |
| 103 | |
| 104 | gd->ram_size = get_ram_size((long *)CFG_SYS_SDRAM_BASE, max_size); |
| 105 | |
| 106 | return 0; |
| 107 | } |