Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 1 | /* |
| 2 | * (C) Copyright 2005-2007 |
| 3 | * Samsung Electronics, |
| 4 | * Kyungmin Park <kyungmin.park@samsung.com> |
| 5 | * |
| 6 | * Derived from omap2420 |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License as |
| 10 | * published by the Free Software Foundation; either version 2 of |
| 11 | * the License, or (at your option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program; if not, write to the Free Software |
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| 21 | * MA 02111-1307 USA |
| 22 | */ |
| 23 | |
| 24 | #include <common.h> |
| 25 | #include <asm/arch/omap2420.h> |
| 26 | #include <asm/io.h> |
| 27 | #include <asm/arch/bits.h> |
| 28 | #include <asm/arch/mux.h> |
| 29 | #include <asm/arch/mem.h> |
| 30 | #include <asm/arch/clocks.h> |
| 31 | #include <asm/arch/sys_proto.h> |
| 32 | #include <asm/arch/sys_info.h> |
| 33 | |
| 34 | #include "mem.h" |
| 35 | |
| 36 | /************************************************************ |
| 37 | * sdelay() - simple spin loop. Will be constant time as |
| 38 | * its generally used in 12MHz bypass conditions only. This |
| 39 | * is necessary until timers are accessible. |
| 40 | * |
| 41 | * not inline to increase chances its in cache when called |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 42 | *************************************************************/ |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 43 | void sdelay(unsigned long loops) |
| 44 | { |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 45 | __asm__("1:\n" "subs %0, %1, #1\n" |
| 46 | "bne 1b":"=r" (loops):"0"(loops)); |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 47 | } |
| 48 | |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 49 | /******************************************************************** |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 50 | * prcm_init() - inits clocks for PRCM as defined in clocks.h |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 51 | * (config II default). |
| 52 | * -- called from SRAM, or Flash (using temp SRAM stack). |
| 53 | ********************************************************************/ |
| 54 | void prcm_init(void) { } |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 55 | |
| 56 | /************************************************************************** |
| 57 | * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow |
| 58 | * command line mem=xyz use all memory with out discontigious support |
| 59 | * compiled in. Could do it at the ATAG, but there really is two banks... |
| 60 | * Called as part of 2nd phase DDR init. |
| 61 | **************************************************************************/ |
| 62 | void make_cs1_contiguous(void) |
| 63 | { |
| 64 | u32 size, a_add_low, a_add_high; |
| 65 | |
| 66 | size = get_sdr_cs_size(SDRC_CS0_OSET); |
| 67 | size /= SZ_32M; /* find size to offset CS1 */ |
| 68 | a_add_high = (size & 3) << 8; /* set up low field */ |
| 69 | a_add_low = (size & 0x3C) >> 2; /* set up high field */ |
| 70 | __raw_writel((a_add_high | a_add_low), SDRC_CS_CFG); |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 71 | |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | /******************************************************** |
| 75 | * mem_ok() - test used to see if timings are correct |
| 76 | * for a part. Helps in gussing which part |
| 77 | * we are currently using. |
| 78 | *******************************************************/ |
| 79 | u32 mem_ok(void) |
| 80 | { |
| 81 | u32 val1, val2; |
| 82 | u32 pattern = 0x12345678; |
| 83 | |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 84 | /* clear pos A */ |
| 85 | __raw_writel(0x0, OMAP2420_SDRC_CS0 + 0x400); |
| 86 | /* pattern to pos B */ |
| 87 | __raw_writel(pattern, OMAP2420_SDRC_CS0); |
| 88 | /* remove pattern off the bus */ |
| 89 | __raw_writel(0x0, OMAP2420_SDRC_CS0 + 4); |
| 90 | /* get pos A value */ |
| 91 | val1 = __raw_readl(OMAP2420_SDRC_CS0 + 0x400); |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 92 | val2 = __raw_readl(OMAP2420_SDRC_CS0); /* get val2 */ |
| 93 | |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 94 | /* see if pos A value changed */ |
| 95 | if ((val1 != 0) || (val2 != pattern)) |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 96 | return (0); |
| 97 | else |
| 98 | return (1); |
| 99 | } |
| 100 | |
| 101 | /******************************************************** |
| 102 | * sdrc_init() - init the sdrc chip selects CS0 and CS1 |
| 103 | * - early init routines, called from flash or |
| 104 | * SRAM. |
| 105 | *******************************************************/ |
| 106 | void sdrc_init(void) |
| 107 | { |
| 108 | #define EARLY_INIT 1 |
| 109 | /* only init up first bank here */ |
| 110 | do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); |
| 111 | } |
| 112 | |
| 113 | /************************************************************************* |
| 114 | * do_sdrc_init(): initialize the SDRAM for use. |
| 115 | * -called from low level code with stack only. |
| 116 | * -code sets up SDRAM timing and muxing for 2422 or 2420. |
| 117 | * -optimal settings can be placed here, or redone after i2c |
| 118 | * inspection of board info |
| 119 | * |
| 120 | * This is a bit ugly, but should handle all memory moduels |
| 121 | * used with the APOLLON. The first time though this code from s_init() |
| 122 | * we configure the first chip select. Later on we come back and |
| 123 | * will configure the 2nd chip select if it exists. |
| 124 | * |
| 125 | **************************************************************************/ |
| 126 | void do_sdrc_init(u32 offset, u32 early) |
| 127 | { |
| 128 | } |
| 129 | |
| 130 | /***************************************************** |
| 131 | * gpmc_init(): init gpmc bus |
| 132 | * Init GPMC for x16, MuxMode (SDRAM in x32). |
| 133 | * This code can only be executed from SRAM or SDRAM. |
| 134 | *****************************************************/ |
| 135 | void gpmc_init(void) |
| 136 | { |
| 137 | u32 mux = 0, mtype, mwidth, rev, tval; |
| 138 | |
| 139 | rev = get_cpu_rev(); |
| 140 | if (rev == CPU_2420_2422_ES1) |
| 141 | tval = 1; |
| 142 | else |
| 143 | tval = 0; /* disable bit switched meaning */ |
| 144 | |
| 145 | /* global settings */ |
| 146 | __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ |
| 147 | __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ |
| 148 | __raw_writel(tval, GPMC_TIMEOUT_CONTROL); /* timeout disable */ |
| 149 | #ifdef CFG_NAND_BOOT |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 150 | /* set nWP, disable limited addr */ |
| 151 | __raw_writel(0x001, GPMC_CONFIG); |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 152 | #else |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 153 | /* set nWP, disable limited addr */ |
| 154 | __raw_writel(0x111, GPMC_CONFIG); |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 155 | #endif |
| 156 | |
| 157 | /* discover bus connection from sysboot */ |
| 158 | if (is_gpmc_muxed() == GPMC_MUXED) |
| 159 | mux = BIT9; |
| 160 | mtype = get_gpmc0_type(); |
| 161 | mwidth = get_gpmc0_width(); |
| 162 | |
| 163 | /* setup cs0 */ |
| 164 | __raw_writel(0x0, GPMC_CONFIG7_0); /* disable current map */ |
| 165 | sdelay(1000); |
| 166 | |
| 167 | #ifdef CFG_NOR_BOOT |
| 168 | __raw_writel(APOLLON_24XX_GPMC_CONFIG1_3, GPMC_CONFIG1_0); |
| 169 | __raw_writel(APOLLON_24XX_GPMC_CONFIG2_3, GPMC_CONFIG2_0); |
| 170 | __raw_writel(APOLLON_24XX_GPMC_CONFIG3_3, GPMC_CONFIG3_0); |
| 171 | __raw_writel(APOLLON_24XX_GPMC_CONFIG4_3, GPMC_CONFIG4_0); |
| 172 | __raw_writel(APOLLON_24XX_GPMC_CONFIG5_3, GPMC_CONFIG5_0); |
| 173 | __raw_writel(APOLLON_24XX_GPMC_CONFIG6_3, GPMC_CONFIG6_0); |
Peter Pearse | 2db916e | 2007-11-15 08:45:13 +0000 | [diff] [blame] | 174 | __raw_writel(APOLLON_24XX_GPMC_CONFIG7_3, GPMC_CONFIG7_0); |
| 175 | #else |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 176 | __raw_writel(APOLLON_24XX_GPMC_CONFIG1_0 | mux | mtype | mwidth, |
| 177 | GPMC_CONFIG1_0); |
| 178 | __raw_writel(APOLLON_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); |
| 179 | __raw_writel(APOLLON_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0); |
| 180 | __raw_writel(APOLLON_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0); |
| 181 | __raw_writel(APOLLON_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); |
| 182 | __raw_writel(APOLLON_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_0); |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 183 | __raw_writel(APOLLON_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0); |
| 184 | #endif |
| 185 | sdelay(2000); |
| 186 | |
| 187 | /* setup cs1 */ |
| 188 | __raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */ |
| 189 | sdelay(1000); |
| 190 | |
| 191 | __raw_writel(APOLLON_24XX_GPMC_CONFIG1_1, GPMC_CONFIG1_1); |
| 192 | __raw_writel(APOLLON_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1); |
| 193 | __raw_writel(APOLLON_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1); |
| 194 | __raw_writel(APOLLON_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1); |
| 195 | __raw_writel(APOLLON_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1); |
| 196 | __raw_writel(APOLLON_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1); |
| 197 | __raw_writel(APOLLON_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); |
| 198 | sdelay(2000); |
| 199 | |
| 200 | /* setup cs2 */ |
Kyungmin Park | 98ba144 | 2008-02-18 14:35:43 +0900 | [diff] [blame] | 201 | __raw_writel(0x0, GPMC_CONFIG7_2); /* disable current map */ |
| 202 | sdelay(1000); |
Peter Pearse | 5ca9881 | 2007-11-09 15:24:26 +0000 | [diff] [blame] | 203 | __raw_writel(APOLLON_24XX_GPMC_CONFIG1_0 | mux | mtype | mwidth, |
| 204 | GPMC_CONFIG1_2); |
| 205 | /* It's same as cs 0 */ |
| 206 | __raw_writel(APOLLON_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_2); |
| 207 | __raw_writel(APOLLON_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_2); |
| 208 | __raw_writel(APOLLON_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_2); |
| 209 | __raw_writel(APOLLON_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_2); |
| 210 | __raw_writel(APOLLON_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_2); |
| 211 | #ifdef CFG_NOR_BOOT |
| 212 | __raw_writel(APOLLON_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_2); |
| 213 | #else |
| 214 | __raw_writel(APOLLON_24XX_GPMC_CONFIG7_2, GPMC_CONFIG7_2); |
| 215 | #endif |
| 216 | |
| 217 | #ifndef CFG_NOR_BOOT |
| 218 | /* setup cs3 */ |
| 219 | __raw_writel(0, GPMC_CONFIG7_3); /* disable any mapping */ |
| 220 | sdelay(1000); |
| 221 | |
| 222 | __raw_writel(APOLLON_24XX_GPMC_CONFIG1_3, GPMC_CONFIG1_3); |
| 223 | __raw_writel(APOLLON_24XX_GPMC_CONFIG2_3, GPMC_CONFIG2_3); |
| 224 | __raw_writel(APOLLON_24XX_GPMC_CONFIG3_3, GPMC_CONFIG3_3); |
| 225 | __raw_writel(APOLLON_24XX_GPMC_CONFIG4_3, GPMC_CONFIG4_3); |
| 226 | __raw_writel(APOLLON_24XX_GPMC_CONFIG5_3, GPMC_CONFIG5_3); |
| 227 | __raw_writel(APOLLON_24XX_GPMC_CONFIG6_3, GPMC_CONFIG6_3); |
| 228 | __raw_writel(APOLLON_24XX_GPMC_CONFIG7_3, GPMC_CONFIG7_3); |
| 229 | #endif |
| 230 | |
| 231 | #ifndef ASYNC_NOR |
| 232 | __raw_writew(0xaa, (APOLLON_CS3_BASE + 0xaaa)); |
| 233 | __raw_writew(0x55, (APOLLON_CS3_BASE + 0x554)); |
| 234 | __raw_writew(0xc0, (APOLLON_CS3_BASE | SYNC_NOR_VALUE)); |
| 235 | #endif |
| 236 | sdelay(2000); |
| 237 | } |