]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/omap2420h4/mem.c
Coding Style cleanup
[karo-tx-uboot.git] / board / omap2420h4 / mem.c
1 /*
2  * (C) Copyright 2004
3  * Texas Instruments, <www.ti.com>
4  * Richard Woodruff <r-woodruff2@ti.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA
20  */
21
22 #include <common.h>
23 #include <asm/arch/omap2420.h>
24 #include <asm/io.h>
25 #include <asm/arch/bits.h>
26 #include <asm/arch/mux.h>
27 #include <asm/arch/mem.h>
28 #include <asm/arch/clocks.h>
29 #include <asm/arch/sys_proto.h>
30 #include <asm/arch/sys_info.h>
31
32 /************************************************************
33  * sdelay() - simple spin loop.  Will be constant time as
34  *  its generally used in 12MHz bypass conditions only.  This
35  *  is necessary until timers are accessible.
36  *
37  *  not inline to increase chances its in cache when called
38  *************************************************************/
39 void sdelay (unsigned long loops)
40 {
41         __asm__ volatile ("1:\n"
42                                           "subs %0, %1, #1\n"
43                                           "bne 1b":"=r" (loops):"0" (loops));
44 }
45
46 /*********************************************************************************
47  * prcm_init() - inits clocks for PRCM as defined in clocks.h (config II default).
48  *   -- called from SRAM, or Flash (using temp SRAM stack).
49  *********************************************************************************/
50 void prcm_init(void)
51 {
52         u32 rev,div;
53 #ifdef CONFIG_PARTIAL_SRAM
54         void (*f_lock_pll) (u32, u32, u32, u32);
55         extern void *_end_vect, *_start;
56
57         f_lock_pll = (void *)((u32)&_end_vect - (u32)&_start + SRAM_VECT_CODE);
58 #endif
59
60         __raw_writel(0, CM_FCLKEN1_CORE);          /* stop all clocks to reduce ringing */
61         __raw_writel(0, CM_FCLKEN2_CORE);          /* may not be necessary */
62         __raw_writel(0, CM_ICLKEN1_CORE);
63         __raw_writel(0, CM_ICLKEN2_CORE);
64
65         __raw_writel(DPLL_OUT, CM_CLKSEL2_PLL); /* set DPLL out */
66         __raw_writel(MPU_DIV, CM_CLKSEL_MPU);   /* set MPU divider */
67         __raw_writel(DSP_DIV, CM_CLKSEL_DSP);   /* set dsp and iva dividers */
68         __raw_writel(GFX_DIV, CM_CLKSEL_GFX);   /* set gfx dividers */
69
70         rev  = get_cpu_rev();
71         if (rev == CPU_2420_ES1 || rev ==  CPU_2422_ES1)
72                 div = BUS_DIV_ES1;
73         else
74                 div     = BUS_DIV;
75         __raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */
76         sdelay(1000);
77
78 #ifndef CONFIG_PARTIAL_SRAM
79         /* If running fully from SRAM this is OK.  The Flash bus drops out for just a little.
80          * but then comes back.  If running from Flash this sequence kills you, thus you need
81          * to run it using CONFIG_PARTIAL_SRAM.
82          */
83         __raw_writel(MODE_BYPASS_FAST, CM_CLKEN_PLL); /* go to bypass, fast relock */
84         wait_on_value(BIT0|BIT1, BIT1, CM_IDLEST_CKGEN, LDELAY); /* wait till in bypass */
85
86         /* set clock selection and dpll dividers. */
87         __raw_writel(DPLL_VAL, CM_CLKSEL1_PLL);  /* set pll for target rate */
88         __raw_writel(COMMIT_DIVIDERS, PRCM_CLKCFG_CTRL); /* commit dividers */
89         sdelay(10000);
90         __raw_writel(DPLL_LOCK, CM_CLKEN_PLL); /* enable dpll */
91         sdelay(10000);
92         wait_on_value(BIT0|BIT1, BIT2, CM_IDLEST_CKGEN, LDELAY);  /*wait for dpll lock */
93 #else
94 /* if running from flash, need to jump to small relocated code area in SRAM.
95  * This is the only safe spot to do configurations from.
96  */
97         (*f_lock_pll)(PRCM_CLKCFG_CTRL, CM_CLKEN_PLL, DPLL_LOCK, CM_IDLEST_CKGEN);
98 #endif
99
100         __raw_writel(DPLL_LOCK|APLL_LOCK, CM_CLKEN_PLL);   /* enable apll */
101         wait_on_value(BIT8, BIT8, CM_IDLEST_CKGEN, LDELAY);     /* wait for apll lock */
102         sdelay(1000);
103 }
104
105 /***********************************************
106  * memif_init() - init the gpmc and sdrc
107  *  - early init routines, called from flash or
108  *  SRAM.
109  ***********************************************/
110 void memif_init(void)
111 {
112         sdrc_init();
113 #ifndef CONFIG_PARTIAL_SRAM  /* don't init if calling from flash */
114         gpmc_init();
115 #endif
116 }
117
118 /********************************************************
119  *  mem_ok() - test used to see if timings are correct
120  *             for a part. Helps in gussing which part
121  *             we are currently using.
122  *******************************************************/
123 u32 mem_ok(void)
124 {  u32 val;
125         __raw_writel(0x0,OMAP2420_SDRC_CS0+0x400);  /* clear pos A */
126         __raw_writel(0x12345678, OMAP2420_SDRC_CS0);/* pattern to pos B */
127         val = __raw_readl(OMAP2420_SDRC_CS0+0x400); /* get pos A value */
128         if (val != 0)                               /* see if pos A value changed*/
129                 return(0);
130         else
131                 return(1);
132 }
133
134 /********************************************************
135  *  sdrc_init() - init the sdrc chip selects CS0 and CS1
136  *  - early init routines, called from flash or
137  *  SRAM.
138  *******************************************************/
139 void sdrc_init(void)
140 {
141         #define EARLY_INIT 1
142         do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT);  /* only init up first bank here */
143 }
144
145 /**********************************************************
146  * do_sdrc_init(): initialize the SDRAM for use.
147  *  -called from low level code with stack only.
148  *  -code sets up SDRAM timing and muxing for 2422 or 2420.
149  *  -optimal settings can be placed here, or redone after i2c
150  *      inspection of board info
151  *
152  * !!! When ES1 comes out need to conditionalize RFR value!!!
153  **********************************************************/
154 void do_sdrc_init(u32 offset, u32 early)
155 {
156         u32 cpu, bug=0, rev, shared=0, cs0=0, pmask=0,first=1;
157         sdrc_data_t *sdata;      /* do not change type */
158
159         static const sdrc_data_t sdrc_2422 =
160         {
161                 H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0, H4_2422_SDRC_ACTIM_CTRLA_0,
162                 H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL_ES1, H4_2422_SDRC_MR_0,
163                 H4_2422_SDRC_DLLA_CTRL, H4_2422_SDRC_DLLB_CTRL
164         };
165         static const sdrc_data_t sdrc_2420 =
166         {
167                 H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0, H4_2420_SDRC_ACTIM_CTRLA_0,
168                 H4_2420_SDRC_ACTIM_CTRLB_0, H4_2420_SDRC_RFR_CTRL_ES1, H4_2420_SDRC_MR_0,
169                 H4_2420_SDRC_DLLA_CTRL, H4_2420_SDRC_DLLB_CTRL
170         };
171
172         if (offset == SDRC_CS0_OSET)
173                 cs0 = shared = 1;  /* int regs shared between both chip select */
174
175         cpu = get_cpu_type();
176
177         /* warning generated, though code generation is correct. this may bite later, but is ok for now.
178          *  there is only so much C code you can do on stack only operation.
179          */
180         if (cpu == CPU_2422)
181                 sdata = &sdrc_2422;
182         else
183                 sdata = &sdrc_2420;
184         __asm__ __volatile__("": : :"memory");
185 #ifdef CONFIG_PARTIAL_SRAM
186         /* u-boot is compiled to run in DDR at 8xxxxxxx.  If we use data here which is not pc relative
187          * we need to get the address correct.  We need to find the current flash mapping to dress up
188          * the initial pointer load.  As long as this is const data we should be ok.
189          */
190         if(early)
191                 sdata = (sdrc_data_t *)(((u32)sdata & 0x0003FFFF) | get_gpmc0_base());
192 #endif
193
194         men_combo:
195
196         if (!early && get_mem_type() == DDR_COMBO) { /* combo part has a shared CKE signal, can't use feature */
197                 pmask = BIT2;
198                 first = 0;      /* trigger ddr_combo init */
199         }
200
201         if (shared) {
202                 __raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG);
203                 __raw_writel(SMART_IDLE|SOFTRESET, SDRC_SYSCONFIG);     /* reset sdrc */
204                 wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);       /* wait till reset done set */
205                 __raw_writel(SMART_IDLE, SDRC_SYSCONFIG);               /* clear soft reset */
206                 __raw_writel(sdata->sdrc_sharing, SDRC_SHARING);
207                 __raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER);
208         }
209         if (first)
210                 __raw_writel(sdata->sdrc_mdcfg_0, SDRC_MCFG_0+offset);
211         else {
212                 __raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER);
213                 __raw_writel(H4_2420_COMBO_MDCFG_0,SDRC_MCFG_0+offset);
214         }
215
216         if (cs0) {
217                 __raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_0);
218                 __raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_0);
219         } else {
220                 __raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_1);
221                 __raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_1);
222         }
223
224         __raw_writel(sdata->sdrc_rfr_ctrl, SDRC_RFR_CTRL+offset);
225
226         /* init sequence for _mDDR_ using manual commands (DDR is a bit different) */
227         __raw_writel(CMD_NOP, SDRC_MANUAL_0+offset);
228         sdelay(5000);  /* susposed to be 100us per design spec for mddr*/
229         __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0+offset);
230         __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset);
231         __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset);
232
233         /*
234          * CSx SDRC Mode Register
235          * Burst length = 4 - DDR memory
236          * Serial mode
237          * CAS latency = x
238          */
239         __raw_writel(sdata->sdrc_mr_0, SDRC_MR_0+offset);
240
241         /* NOTE: ES1 242x _BUG_ DLL */
242         rev  = get_cpu_rev();
243         if (rev == CPU_2420_ES1 || rev ==  CPU_2422_ES1)
244                 bug = BIT0;
245         /* enable & load up DLL with good value for 75MHz, and set phase to 90% */
246         if (shared) {
247                 __raw_writel(sdata->sdrc_dlla_ctrl, SDRC_DLLA_CTRL);
248                 __raw_writel(sdata->sdrc_dlla_ctrl & ~(BIT2|bug), SDRC_DLLA_CTRL);
249                 __raw_writel(sdata->sdrc_dllb_ctrl, SDRC_DLLB_CTRL);
250                 __raw_writel(sdata->sdrc_dllb_ctrl & ~(BIT2|bug) , SDRC_DLLB_CTRL);
251         }
252         sdelay(9000);
253         if (!first || mem_ok()) /* passed test or 2nd bank init */
254                 return;
255         else {
256                 first = 0;
257                 goto men_combo;
258         }
259 }
260
261
262 /*****************************************************
263  * gpmc_init(): init gpmc bus
264  * Init GPMC for x16, MuxMode (SDRAM in x32).
265  * This code can only be executed from SRAM or SDRAM.
266  *****************************************************/
267 void gpmc_init(void)
268 {
269         u32 mux=0, mtype, mwidth;
270
271         /* global settings */
272         __raw_writel(0x10, GPMC_SYSCONFIG);     /* smart idle */
273         __raw_writel(0x0, GPMC_IRQENABLE);      /* isr's sources masked */
274         __raw_writel(0x1, GPMC_TIMEOUT_CONTROL);/* timeout disable */
275         __raw_writel(0x111, GPMC_CONFIG);       /* set nWP, disable limited addr */
276
277         /* discover bus connection from sysboot */
278         if (is_gpmc_muxed() == GPMC_MUXED)
279                 mux = BIT9;
280         mtype = get_gpmc0_type();
281         mwidth = get_gpmc0_width();
282
283         /* setup cs0 */
284         __raw_writel(0x0, GPMC_CONFIG7_0);      /* disable current map */
285         sdelay(1000);
286         __raw_writel(H4_24XX_GPMC_CONFIG1_0|mux|mtype|mwidth, GPMC_CONFIG1_0);
287         /* __raw_writel(H4_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); */
288         __raw_writel(H4_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0);
289         __raw_writel(H4_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0);
290         /* __raw_writel(H4_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); */
291         __raw_writel(H4_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0);/* enable new mapping */
292         sdelay(2000);
293
294         /* setup cs1 */
295         __raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */
296         sdelay(1000);
297         __raw_writel(H4_24XX_GPMC_CONFIG1_1|mux, GPMC_CONFIG1_1);
298         __raw_writel(H4_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1);
299         __raw_writel(H4_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1);
300         __raw_writel(H4_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1);
301         __raw_writel(H4_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1);
302         __raw_writel(H4_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1);
303         __raw_writel(H4_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); /* enable mapping */
304         sdelay(2000);
305 }