]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm926ejs/spear/spl.c
3 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
5 * Copyright (C) 2012 Stefan Roese <sr@denx.de>
7 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm/arch/hardware.h>
15 #include <asm/arch/spr_defs.h>
16 #include <asm/arch/spr_misc.h>
17 #include <asm/arch/spr_syscntl.h>
18 #include <linux/mtd/st_smi.h>
20 static void ddr_clock_init(void)
22 struct misc_regs
*misc_p
= (struct misc_regs
*)CONFIG_SPEAR_MISCBASE
;
25 clkenb
= readl(&misc_p
->periph1_clken
);
26 clkenb
&= ~PERIPH_MPMCMSK
;
27 clkenb
|= PERIPH_MPMC_WE
;
29 /* Intentionally done twice */
30 writel(clkenb
, &misc_p
->periph1_clken
);
31 writel(clkenb
, &misc_p
->periph1_clken
);
33 ddrpll
= readl(&misc_p
->pll_ctr_reg
);
34 ddrpll
&= ~MEM_CLK_SEL_MSK
;
36 ddrpll
|= MEM_CLK_HCLK
;
37 #elif (CONFIG_DDR_2HCLK)
38 ddrpll
|= MEM_CLK_2HCLK
;
39 #elif (CONFIG_DDR_PLL2)
40 ddrpll
|= MEM_CLK_PLL2
;
42 #error "please define one of CONFIG_DDR_(HCLK|2HCLK|PLL2)"
44 writel(ddrpll
, &misc_p
->pll_ctr_reg
);
46 writel(readl(&misc_p
->periph1_clken
) | PERIPH_MPMC_EN
,
47 &misc_p
->periph1_clken
);
50 static void mpmc_init_values(void)
53 u32
*mpmc_reg_p
= (u32
*)CONFIG_SPEAR_MPMCBASE
;
54 u32
*mpmc_val_p
= &mpmc_conf_vals
[0];
56 for (i
= 0; i
< CONFIG_SPEAR_MPMCREGS
; i
++, mpmc_reg_p
++, mpmc_val_p
++)
57 writel(*mpmc_val_p
, mpmc_reg_p
);
59 mpmc_reg_p
= (u32
*)CONFIG_SPEAR_MPMCBASE
;
62 * MPMC controller start
63 * MPMC waiting for DLLLOCKREG high
65 writel(0x01000100, &mpmc_reg_p
[7]);
67 while (!(readl(&mpmc_reg_p
[3]) & 0x10000))
71 static void mpmc_init(void)
73 /* Clock related settings for DDR */
77 * DDR pad register bits are different for different SoCs
78 * Compensation values are also handled separately
82 /* Initialize mpmc register values */
86 static void pll_init(void)
88 struct misc_regs
*misc_p
= (struct misc_regs
*)CONFIG_SPEAR_MISCBASE
;
91 writel(FREQ_332
, &misc_p
->pll1_frq
);
92 writel(0x1C0A, &misc_p
->pll1_cntl
);
93 writel(0x1C0E, &misc_p
->pll1_cntl
);
94 writel(0x1C06, &misc_p
->pll1_cntl
);
95 writel(0x1C0E, &misc_p
->pll1_cntl
);
97 writel(FREQ_332
, &misc_p
->pll2_frq
);
98 writel(0x1C0A, &misc_p
->pll2_cntl
);
99 writel(0x1C0E, &misc_p
->pll2_cntl
);
100 writel(0x1C06, &misc_p
->pll2_cntl
);
101 writel(0x1C0E, &misc_p
->pll2_cntl
);
103 /* wait for pll locks */
104 while (!(readl(&misc_p
->pll1_cntl
) & 0x1))
106 while (!(readl(&misc_p
->pll2_cntl
) & 0x1))
110 static void mac_init(void)
112 struct misc_regs
*misc_p
= (struct misc_regs
*)CONFIG_SPEAR_MISCBASE
;
114 writel(readl(&misc_p
->periph1_clken
) & (~PERIPH_GMAC
),
115 &misc_p
->periph1_clken
);
117 writel(SYNTH23
, &misc_p
->gmac_synth_clk
);
119 switch (get_socrev()) {
120 case SOC_SPEAR600_AA
:
121 case SOC_SPEAR600_AB
:
122 case SOC_SPEAR600_BA
:
123 case SOC_SPEAR600_BB
:
124 case SOC_SPEAR600_BC
:
125 case SOC_SPEAR600_BD
:
126 writel(0x0, &misc_p
->gmac_ctr_reg
);
132 writel(0x4, &misc_p
->gmac_ctr_reg
);
136 writel(readl(&misc_p
->periph1_clken
) | PERIPH_GMAC
,
137 &misc_p
->periph1_clken
);
139 writel(readl(&misc_p
->periph1_rst
) | PERIPH_GMAC
,
140 &misc_p
->periph1_rst
);
141 writel(readl(&misc_p
->periph1_rst
) & (~PERIPH_GMAC
),
142 &misc_p
->periph1_rst
);
145 static void sys_init(void)
147 struct misc_regs
*misc_p
= (struct misc_regs
*)CONFIG_SPEAR_MISCBASE
;
148 struct syscntl_regs
*syscntl_p
=
149 (struct syscntl_regs
*)CONFIG_SPEAR_SYSCNTLBASE
;
151 /* Set system state to SLOW */
152 writel(SLOW
, &syscntl_p
->scctrl
);
153 writel(PLL_TIM
<< 3, &syscntl_p
->scpllctrl
);
155 /* Initialize PLLs */
159 * Ethernet configuration
160 * To be done only if the tftp boot is not selected already
161 * Boot code ensures the correct configuration in tftp booting
163 if (!tftp_boot_selected())
166 writel(RTC_DISABLE
| PLLTIMEEN
, &misc_p
->periph_clk_cfg
);
167 writel(0x555, &misc_p
->amba_clk_cfg
);
169 writel(NORMAL
, &syscntl_p
->scctrl
);
171 /* Wait for system to switch to normal mode */
172 while (((readl(&syscntl_p
->scctrl
) >> MODE_SHIFT
) & MODE_MASK
)
181 * @return SOC_SPEARXXX
185 #if defined(CONFIG_SPEAR600)
186 struct misc_regs
*misc_p
= (struct misc_regs
*)CONFIG_SPEAR_MISCBASE
;
187 u32 soc_id
= readl(&misc_p
->soc_core_id
);
188 u32 pri_socid
= (soc_id
>> SOC_PRI_SHFT
) & 0xFF;
189 u32 sec_socid
= (soc_id
>> SOC_SEC_SHFT
) & 0xFF;
191 if ((pri_socid
== 'B') && (sec_socid
== 'B'))
192 return SOC_SPEAR600_BB
;
193 else if ((pri_socid
== 'B') && (sec_socid
== 'C'))
194 return SOC_SPEAR600_BC
;
195 else if ((pri_socid
== 'B') && (sec_socid
== 'D'))
196 return SOC_SPEAR600_BD
;
197 else if (soc_id
== 0)
198 return SOC_SPEAR600_BA
;
201 #elif defined(CONFIG_SPEAR300)
203 #elif defined(CONFIG_SPEAR310)
205 #elif defined(CONFIG_SPEAR320)
211 * SNOR (Serial NOR flash) related functions
213 static void snor_init(void)
215 struct smi_regs
*const smicntl
=
216 (struct smi_regs
* const)CONFIG_SYS_SMI_BASE
;
218 /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */
219 writel(HOLD1
| FAST_MODE
| BANK_EN
| DSEL_TIME
| PRESCAL4
,
223 u32
spl_boot_device(void)
227 /* Currently only SNOR is supported as the only */
228 if (snor_boot_selected()) {
229 /* SNOR-SMI initialization */
232 mode
= BOOT_DEVICE_NOR
;
238 void board_init_f(ulong dummy
)
240 struct misc_regs
*misc_p
= (struct misc_regs
*)CONFIG_SPEAR_MISCBASE
;
242 /* Initialize PLLs */
245 preloader_console_init();
248 /* Enable IPs (release reset) */
249 writel(PERIPH_RST_ALL
, &misc_p
->periph1_rst
);
251 /* Initialize MPMC */
252 puts("Configure DDR\n");
256 board_init_r(NULL
, 0);