]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm926ejs/kirkwood/cpu.c
c63e8641f2146e0606c14a2499d1a8a4f2391570
3 * Marvell Semiconductor <www.marvell.com>
4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
6 * See file CREDITS for list of people who contributed to this
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 #include <asm/cache.h>
28 #include <u-boot/md5.h>
29 #include <asm/arch/kirkwood.h>
34 void reset_cpu(unsigned long ignored
)
36 struct kwcpu_registers
*cpureg
=
37 (struct kwcpu_registers
*)KW_CPU_REG_BASE
;
39 writel(readl(&cpureg
->rstoutn_mask
) | (1 << 2),
40 &cpureg
->rstoutn_mask
);
41 writel(readl(&cpureg
->sys_soft_rst
) | 1,
42 &cpureg
->sys_soft_rst
);
47 * Generates Ramdom hex number reading some time varient system registers
48 * and using md5 algorithm
50 unsigned char get_random_hex(void)
57 * in case of 88F6281/88F6192 A0,
58 * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470
59 * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and
60 * Does not have names at this moment (no errata available)
62 writel(readl(KW_REG_UNDOC_0x1478
) & ~(1 << 7), KW_REG_UNDOC_0x1478
);
63 for (i
= 0; i
< BUFLEN
; i
++) {
64 inbuf
[i
] = readl(KW_REG_UNDOC_0x1470
);
66 md5((u8
*) inbuf
, (BUFLEN
* sizeof(u32
)), outbuf
);
67 return outbuf
[outbuf
[7] % 0x0f];
72 * Used with the Base register to set the address window size and location.
73 * Must be programmed from LSB to MSB as sequence of ones followed by
74 * sequence of zeros. The number of ones specifies the size of the window in
75 * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte).
76 * NOTE: A value of 0x0 specifies 64-KByte size.
78 unsigned int kw_winctrl_calcsize(unsigned int sizeval
)
82 u32 val
= sizeval
>> 1;
84 for (i
= 0; val
> 0x10000; i
++) {
88 return (0x0000ffff & j
);
92 * kw_config_adr_windows - Configure address Windows
94 * There are 8 address windows supported by Kirkwood Soc to addess different
95 * devices. Each window can be configured for size, BAR and remap addr
96 * Below configuration is standard for most of the cases
98 * If remap function not used, remap_lo must be set as base
100 * Reference Documentation:
101 * Mbus-L to Mbus Bridge Registers Configuration.
102 * (Sec 25.1 and 25.3 of Datasheet)
104 int kw_config_adr_windows(void)
106 struct kwwin_registers
*winregs
=
107 (struct kwwin_registers
*)KW_CPU_WIN_BASE
;
109 /* Window 0: PCIE MEM address space */
110 writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE
,
111 KWCPU_ATTR_PCIE_MEM
, KWCPU_WIN_ENABLE
), &winregs
[0].ctrl
);
113 writel(KW_DEFADR_PCI_MEM
, &winregs
[0].base
);
114 writel(KW_DEFADR_PCI_MEM
, &winregs
[0].remap_lo
);
115 writel(0x0, &winregs
[0].remap_hi
);
117 /* Window 1: PCIE IO address space */
118 writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE
,
119 KWCPU_ATTR_PCIE_IO
, KWCPU_WIN_ENABLE
), &winregs
[1].ctrl
);
120 writel(KW_DEFADR_PCI_IO
, &winregs
[1].base
);
121 writel(KW_DEFADR_PCI_IO_REMAP
, &winregs
[1].remap_lo
);
122 writel(0x0, &winregs
[1].remap_hi
);
124 /* Window 2: NAND Flash address space */
125 writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY
,
126 KWCPU_ATTR_NANDFLASH
, KWCPU_WIN_ENABLE
), &winregs
[2].ctrl
);
127 writel(KW_DEFADR_NANDF
, &winregs
[2].base
);
128 writel(KW_DEFADR_NANDF
, &winregs
[2].remap_lo
);
129 writel(0x0, &winregs
[2].remap_hi
);
131 /* Window 3: SPI Flash address space */
132 writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY
,
133 KWCPU_ATTR_SPIFLASH
, KWCPU_WIN_ENABLE
), &winregs
[3].ctrl
);
134 writel(KW_DEFADR_SPIF
, &winregs
[3].base
);
135 writel(KW_DEFADR_SPIF
, &winregs
[3].remap_lo
);
136 writel(0x0, &winregs
[3].remap_hi
);
138 /* Window 4: BOOT Memory address space */
139 writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY
,
140 KWCPU_ATTR_BOOTROM
, KWCPU_WIN_ENABLE
), &winregs
[4].ctrl
);
141 writel(KW_DEFADR_BOOTROM
, &winregs
[4].base
);
143 /* Window 5: Security SRAM address space */
144 writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM
,
145 KWCPU_ATTR_SASRAM
, KWCPU_WIN_ENABLE
), &winregs
[5].ctrl
);
146 writel(KW_DEFADR_SASRAM
, &winregs
[5].base
);
148 /* Window 6-7: Disabled */
149 writel(KWCPU_WIN_DISABLE
, &winregs
[6].ctrl
);
150 writel(KWCPU_WIN_DISABLE
, &winregs
[7].ctrl
);
156 * kw_config_gpio - GPIO configuration
158 void kw_config_gpio(u32 gpp0_oe_val
, u32 gpp1_oe_val
, u32 gpp0_oe
, u32 gpp1_oe
)
160 struct kwgpio_registers
*gpio0reg
=
161 (struct kwgpio_registers
*)KW_GPIO0_BASE
;
162 struct kwgpio_registers
*gpio1reg
=
163 (struct kwgpio_registers
*)KW_GPIO1_BASE
;
165 /* Init GPIOS to default values as per board requirement */
166 writel(gpp0_oe_val
, &gpio0reg
->dout
);
167 writel(gpp1_oe_val
, &gpio1reg
->dout
);
168 writel(gpp0_oe
, &gpio0reg
->oe
);
169 writel(gpp1_oe
, &gpio1reg
->oe
);
173 * kw_config_mpp - Multi-Purpose Pins Functionality configuration
175 * Each MPP can be configured to different functionality through
176 * MPP control register, ref (sec 6.1 of kirkwood h/w specification)
178 * There are maximum 64 Multi-Pourpose Pins on Kirkwood
179 * Each MPP functionality can be configuration by a 4bit value
180 * of MPP control reg, the value and associated functionality depends
181 * upon used SoC varient
183 int kw_config_mpp(u32 mpp0_7
, u32 mpp8_15
, u32 mpp16_23
, u32 mpp24_31
,
184 u32 mpp32_39
, u32 mpp40_47
, u32 mpp48_55
)
186 u32
*mppreg
= (u32
*) KW_MPP_BASE
;
188 /* program mpp registers */
189 writel(mpp0_7
, &mppreg
[0]);
190 writel(mpp8_15
, &mppreg
[1]);
191 writel(mpp16_23
, &mppreg
[2]);
192 writel(mpp24_31
, &mppreg
[3]);
193 writel(mpp32_39
, &mppreg
[4]);
194 writel(mpp40_47
, &mppreg
[5]);
195 writel(mpp48_55
, &mppreg
[6]);
200 * SYSRSTn Duration Counter Support
202 * Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
203 * When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
204 * The SYSRSTn duration counter is useful for implementing a manufacturer
205 * or factory reset. Upon a long reset assertion that is greater than a
206 * pre-configured environment variable value for sysrstdelay,
207 * The counter value is stored in the SYSRSTn Length Counter Register
208 * The counter is based on the 25-MHz reference clock (40ns)
209 * It is a 29-bit counter, yielding a maximum counting duration of
210 * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
211 * it remains at this value until counter reset is triggered by setting
212 * bit 31 of KW_REG_SYSRST_CNT
214 static void kw_sysrst_action(void)
217 char *s
= getenv("sysrstcmd");
220 debug("Error.. %s failed, check sysrstcmd\n",
225 debug("Starting %s process...\n", __FUNCTION__
);
226 #if !defined(CONFIG_SYS_HUSH_PARSER)
227 ret
= run_command (s
, 0);
229 ret
= parse_string_outer(s
, FLAG_PARSE_SEMICOLON
230 | FLAG_EXIT_FROM_LOOP
);
233 debug("Error.. %s failed\n", __FUNCTION__
);
235 debug("%s process finished\n", __FUNCTION__
);
238 static void kw_sysrst_check(void)
240 u32 sysrst_cnt
, sysrst_dly
;
244 * no action if sysrstdelay environment variable is not defined
246 s
= getenv("sysrstdelay");
250 /* read sysrstdelay value */
251 sysrst_dly
= (u32
) simple_strtoul(s
, NULL
, 10);
253 /* read SysRst Length counter register (bits 28:0) */
254 sysrst_cnt
= (0x1fffffff & readl(KW_REG_SYSRST_CNT
));
255 debug("H/w Rst hold time: %d.%d secs\n",
256 sysrst_cnt
/ SYSRST_CNT_1SEC_VAL
,
257 sysrst_cnt
% SYSRST_CNT_1SEC_VAL
);
259 /* clear the counter for next valid read*/
260 writel(1 << 31, KW_REG_SYSRST_CNT
);
264 * if H/w Reset key is pressed and hold for time
265 * more than sysrst_dly in seconds
267 if (sysrst_cnt
>= SYSRST_CNT_1SEC_VAL
* sysrst_dly
)
271 #if defined(CONFIG_DISPLAY_CPUINFO)
272 int print_cpuinfo(void)
274 char *name
= "Unknown";
276 switch (readl(KW_REG_DEVICE_ID
) & 0x03) {
284 printf("SoC: Unsupported Kirkwood\n");
287 printf("SoC: Kirkwood %s\n", name
);
290 #endif /* CONFIG_DISPLAY_CPUINFO */
292 #ifdef CONFIG_ARCH_CPU_INIT
293 int arch_cpu_init(void)
296 struct kwcpu_registers
*cpureg
=
297 (struct kwcpu_registers
*)KW_CPU_REG_BASE
;
299 /* Linux expects` the internal registers to be at 0xf1000000 */
300 writel(KW_REGS_PHY_BASE
, KW_OFFSET_REG
);
302 /* Enable and invalidate L2 cache in write through mode */
303 writel(readl(&cpureg
->l2_cfg
) | 0x18, &cpureg
->l2_cfg
);
304 invalidate_l2_cache();
306 kw_config_adr_windows();
308 #ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
310 * Configures the I/O voltage of the pads connected to Egigabit
311 * Ethernet interface to 1.8V
312 * By defult it is set to 3.3V
314 reg
= readl(KW_REG_MPP_OUT_DRV_REG
);
316 writel(reg
, KW_REG_MPP_OUT_DRV_REG
);
318 #ifdef CONFIG_KIRKWOOD_EGIGA_INIT
320 * Set egiga port0/1 in normal functional mode
321 * This is required becasue on kirkwood by default ports are in reset mode
322 * OS egiga driver may not have provision to set them in normal mode
323 * and if u-boot is build without network support, network may fail at OS level
325 reg
= readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0));
326 reg
&= ~(1 << 4); /* Clear PortReset Bit */
327 writel(reg
, (KWGBE_PORT_SERIAL_CONTROL1_REG(0)));
328 reg
= readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1));
329 reg
&= ~(1 << 4); /* Clear PortReset Bit */
330 writel(reg
, (KWGBE_PORT_SERIAL_CONTROL1_REG(1)));
332 #ifdef CONFIG_KIRKWOOD_PCIE_INIT
334 * Enable PCI Express Port0
336 reg
= readl(&cpureg
->ctrl_stat
);
337 reg
|= (1 << 0); /* Set PEX0En Bit */
338 writel(reg
, &cpureg
->ctrl_stat
);
342 #endif /* CONFIG_ARCH_CPU_INIT */
345 * SOC specific misc init
347 #if defined(CONFIG_ARCH_MISC_INIT)
348 int arch_misc_init(void)
352 /*CPU streaming & write allocate */
353 temp
= readfr_extra_feature_reg();
354 temp
&= ~(1 << 28); /* disable wr alloc */
355 writefr_extra_feature_reg(temp
);
357 temp
= readfr_extra_feature_reg();
358 temp
&= ~(1 << 29); /* streaming disabled */
359 writefr_extra_feature_reg(temp
);
361 /* L2Cache settings */
362 temp
= readfr_extra_feature_reg();
363 /* Disable L2C pre fetch - Set bit 24 */
365 /* enable L2C - Set bit 22 */
367 writefr_extra_feature_reg(temp
);
370 /* Change reset vector to address 0x0 */
372 set_cr(temp
& ~CR_V
);
374 /* checks and execute resset to factory event */
379 #endif /* CONFIG_ARCH_MISC_INIT */
382 int cpu_eth_init(bd_t
*bis
)
384 mvgbe_initialize(bis
);