2 * arch/ppc/platforms/ev64360.c
4 * Board setup routines for the Marvell EV-64360-BP Evaluation Board.
6 * Author: Lee Nicks <allinux@gmail.com>
8 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
9 * Based on code done by - Mark A. Greer <mgreer@mvista.com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 #include <linux/config.h>
17 #include <linux/kernel.h>
18 #include <linux/pci.h>
19 #include <linux/kdev_t.h>
20 #include <linux/console.h>
21 #include <linux/initrd.h>
22 #include <linux/root_dev.h>
23 #include <linux/delay.h>
24 #include <linux/seq_file.h>
25 #include <linux/bootmem.h>
26 #include <linux/mtd/physmap.h>
27 #include <linux/mv643xx.h>
28 #include <linux/platform_device.h>
30 #include <linux/bootimg.h>
36 #include <asm/bootinfo.h>
37 #include <asm/ppcboot.h>
38 #include <asm/mv64x60.h>
39 #include <asm/machdep.h>
40 #include <platforms/ev64360.h>
42 #define BOARD_VENDOR "Marvell"
43 #define BOARD_MACHINE "EV-64360-BP"
45 static struct mv64x60_handle bh
;
46 static void __iomem
*sram_base
;
48 static u32 ev64360_flash_size_0
;
49 static u32 ev64360_flash_size_1
;
51 static u32 ev64360_bus_frequency
;
53 unsigned char __res
[sizeof(bd_t
)];
58 ev64360_map_irq(struct pci_dev
*dev
, unsigned char idsel
, unsigned char pin
)
64 ev64360_setup_bridge(void)
66 struct mv64x60_setup_info si
;
69 memset(&si
, 0, sizeof(si
));
71 si
.phys_reg_base
= CONFIG_MV64X60_NEW_BASE
;
74 si
.pci_1
.enable_bus
= 1;
75 si
.pci_1
.pci_io
.cpu_base
= EV64360_PCI1_IO_START_PROC_ADDR
;
76 si
.pci_1
.pci_io
.pci_base_hi
= 0;
77 si
.pci_1
.pci_io
.pci_base_lo
= EV64360_PCI1_IO_START_PCI_ADDR
;
78 si
.pci_1
.pci_io
.size
= EV64360_PCI1_IO_SIZE
;
79 si
.pci_1
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
80 si
.pci_1
.pci_mem
[0].cpu_base
= EV64360_PCI1_MEM_START_PROC_ADDR
;
81 si
.pci_1
.pci_mem
[0].pci_base_hi
= EV64360_PCI1_MEM_START_PCI_HI_ADDR
;
82 si
.pci_1
.pci_mem
[0].pci_base_lo
= EV64360_PCI1_MEM_START_PCI_LO_ADDR
;
83 si
.pci_1
.pci_mem
[0].size
= EV64360_PCI1_MEM_SIZE
;
84 si
.pci_1
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
85 si
.pci_1
.pci_cmd_bits
= 0;
86 si
.pci_1
.latency_timer
= 0x80;
88 si
.pci_0
.enable_bus
= 0;
89 si
.pci_1
.enable_bus
= 0;
92 for (i
= 0; i
< MV64x60_CPU2MEM_WINDOWS
; i
++) {
93 #if defined(CONFIG_NOT_COHERENT_CACHE)
94 si
.cpu_prot_options
[i
] = 0;
95 si
.enet_options
[i
] = MV64360_ENET2MEM_SNOOP_NONE
;
96 si
.mpsc_options
[i
] = MV64360_MPSC2MEM_SNOOP_NONE
;
97 si
.idma_options
[i
] = MV64360_IDMA2MEM_SNOOP_NONE
;
99 si
.pci_1
.acc_cntl_options
[i
] =
100 MV64360_PCI_ACC_CNTL_SNOOP_NONE
|
101 MV64360_PCI_ACC_CNTL_SWAP_NONE
|
102 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES
|
103 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES
;
105 si
.cpu_prot_options
[i
] = 0;
106 si
.enet_options
[i
] = MV64360_ENET2MEM_SNOOP_NONE
; /* errata */
107 si
.mpsc_options
[i
] = MV64360_MPSC2MEM_SNOOP_NONE
; /* errata */
108 si
.idma_options
[i
] = MV64360_IDMA2MEM_SNOOP_NONE
; /* errata */
110 si
.pci_1
.acc_cntl_options
[i
] =
111 MV64360_PCI_ACC_CNTL_SNOOP_WB
|
112 MV64360_PCI_ACC_CNTL_SWAP_NONE
|
113 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES
|
114 MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES
;
118 if (mv64x60_init(&bh
, &si
))
119 printk(KERN_WARNING
"Bridge initialization failed.\n");
122 pci_dram_offset
= 0; /* sys mem at same addr on PCI & cpu bus */
123 ppc_md
.pci_swizzle
= common_swizzle
;
124 ppc_md
.pci_map_irq
= ev64360_map_irq
;
125 ppc_md
.pci_exclude_device
= mv64x60_pci_exclude_device
;
127 mv64x60_set_bus(&bh
, 1, 0);
128 bh
.hose_b
->first_busno
= 0;
129 bh
.hose_b
->last_busno
= 0xff;
133 /* Bridge & platform setup routines */
135 ev64360_intr_setup(void)
137 /* MPP 8, 9, and 10 */
138 mv64x60_clr_bits(&bh
, MV64x60_MPP_CNTL_1
, 0xfff);
141 * Define GPP 8,9,and 10 interrupt polarity as active low
142 * input signal and level triggered
144 mv64x60_set_bits(&bh
, MV64x60_GPP_LEVEL_CNTL
, 0x700);
145 mv64x60_clr_bits(&bh
, MV64x60_GPP_IO_CNTL
, 0x700);
147 /* Config GPP intr ctlr to respond to level trigger */
148 mv64x60_set_bits(&bh
, MV64x60_COMM_ARBITER_CNTL
, (1<<10));
150 /* Erranum FEr PCI-#8 */
151 mv64x60_clr_bits(&bh
, MV64x60_PCI0_CMD
, (1<<5) | (1<<9));
152 mv64x60_clr_bits(&bh
, MV64x60_PCI1_CMD
, (1<<5) | (1<<9));
155 * Dismiss and then enable interrupt on GPP interrupt cause
158 mv64x60_write(&bh
, MV64x60_GPP_INTR_CAUSE
, ~0x700);
159 mv64x60_set_bits(&bh
, MV64x60_GPP_INTR_MASK
, 0x700);
162 * Dismiss and then enable interrupt on CPU #0 high cause reg
163 * BIT25 summarizes GPP interrupts 8-15
165 mv64x60_set_bits(&bh
, MV64360_IC_CPU0_INTR_MASK_HI
, (1<<25));
169 ev64360_setup_peripherals(void)
173 /* Set up window for boot CS */
174 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2BOOT_WIN
,
175 EV64360_BOOT_WINDOW_BASE
, EV64360_BOOT_WINDOW_SIZE
, 0);
176 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2BOOT_WIN
);
178 /* We only use the 32-bit flash */
179 mv64x60_get_32bit_window(&bh
, MV64x60_CPU2BOOT_WIN
, &base
,
180 &ev64360_flash_size_0
);
181 ev64360_flash_size_1
= 0;
183 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_1_WIN
,
184 EV64360_RTC_WINDOW_BASE
, EV64360_RTC_WINDOW_SIZE
, 0);
185 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_1_WIN
);
187 TODC_INIT(TODC_TYPE_DS1501
, 0, 0,
188 ioremap(EV64360_RTC_WINDOW_BASE
, EV64360_RTC_WINDOW_SIZE
), 8);
190 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2SRAM_WIN
,
191 EV64360_INTERNAL_SRAM_BASE
, MV64360_SRAM_SIZE
, 0);
192 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2SRAM_WIN
);
193 sram_base
= ioremap(EV64360_INTERNAL_SRAM_BASE
, MV64360_SRAM_SIZE
);
195 /* Set up Enet->SRAM window */
196 mv64x60_set_32bit_window(&bh
, MV64x60_ENET2MEM_4_WIN
,
197 EV64360_INTERNAL_SRAM_BASE
, MV64360_SRAM_SIZE
, 0x2);
198 bh
.ci
->enable_window_32bit(&bh
, MV64x60_ENET2MEM_4_WIN
);
200 /* Give enet r/w access to memory region */
201 mv64x60_set_bits(&bh
, MV64360_ENET2MEM_ACC_PROT_0
, (0x3 << (4 << 1)));
202 mv64x60_set_bits(&bh
, MV64360_ENET2MEM_ACC_PROT_1
, (0x3 << (4 << 1)));
203 mv64x60_set_bits(&bh
, MV64360_ENET2MEM_ACC_PROT_2
, (0x3 << (4 << 1)));
205 mv64x60_clr_bits(&bh
, MV64x60_PCI1_PCI_DECODE_CNTL
, (1 << 3));
206 mv64x60_clr_bits(&bh
, MV64x60_TIMR_CNTR_0_3_CNTL
,
207 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)));
209 #if defined(CONFIG_NOT_COHERENT_CACHE)
210 mv64x60_write(&bh
, MV64360_SRAM_CONFIG
, 0x00160000);
212 mv64x60_write(&bh
, MV64360_SRAM_CONFIG
, 0x001600b2);
216 * Setting the SRAM to 0. Note that this generates parity errors on
217 * internal data path in SRAM since it's first time accessing it
218 * while after reset it's not configured.
220 memset(sram_base
, 0, MV64360_SRAM_SIZE
);
222 /* set up PCI interrupt controller */
223 ev64360_intr_setup();
227 ev64360_setup_arch(void)
230 ppc_md
.progress("ev64360_setup_arch: enter", 0);
234 #ifdef CONFIG_BLK_DEV_INITRD
236 ROOT_DEV
= Root_RAM0
;
239 #ifdef CONFIG_ROOT_NFS
242 ROOT_DEV
= Root_SDA2
;
246 * Set up the L2CR register.
248 _set_L2CR(L2CR_L2E
| L2CR_L2PE
);
251 ppc_md
.progress("ev64360_setup_arch: calling setup_bridge", 0);
253 ev64360_setup_bridge();
254 ev64360_setup_peripherals();
255 ev64360_bus_frequency
= ev64360_bus_freq();
257 printk(KERN_INFO
"%s %s port (C) 2005 Lee Nicks "
258 "(allinux@gmail.com)\n", BOARD_VENDOR
, BOARD_MACHINE
);
260 ppc_md
.progress("ev64360_setup_arch: exit", 0);
263 /* Platform device data fixup routines. */
264 #if defined(CONFIG_SERIAL_MPSC)
266 ev64360_fixup_mpsc_pdata(struct platform_device
*pdev
)
268 struct mpsc_pdata
*pdata
;
270 pdata
= (struct mpsc_pdata
*)pdev
->dev
.platform_data
;
272 pdata
->max_idle
= 40;
273 pdata
->default_baud
= EV64360_DEFAULT_BAUD
;
274 pdata
->brg_clk_src
= EV64360_MPSC_CLK_SRC
;
276 * TCLK (not SysCLk) is routed to BRG, then to the MPSC. On most parts,
277 * TCLK == SysCLK but on 64460, they are separate pins.
278 * SysCLK can go up to 200 MHz but TCLK can only go up to 133 MHz.
280 pdata
->brg_clk_freq
= min(ev64360_bus_frequency
, MV64x60_TCLK_FREQ_MAX
);
284 #if defined(CONFIG_MV643XX_ETH)
286 ev64360_fixup_eth_pdata(struct platform_device
*pdev
)
288 struct mv643xx_eth_platform_data
*eth_pd
;
289 static u16 phy_addr
[] = {
290 EV64360_ETH0_PHY_ADDR
,
291 EV64360_ETH1_PHY_ADDR
,
292 EV64360_ETH2_PHY_ADDR
,
295 eth_pd
= pdev
->dev
.platform_data
;
296 eth_pd
->force_phy_addr
= 1;
297 eth_pd
->phy_addr
= phy_addr
[pdev
->id
];
298 eth_pd
->tx_queue_size
= EV64360_ETH_TX_QUEUE_SIZE
;
299 eth_pd
->rx_queue_size
= EV64360_ETH_RX_QUEUE_SIZE
;
304 ev64360_platform_notify(struct device
*dev
)
308 void ((*rtn
)(struct platform_device
*pdev
));
310 #if defined(CONFIG_SERIAL_MPSC)
311 { MPSC_CTLR_NAME
".0", ev64360_fixup_mpsc_pdata
},
312 { MPSC_CTLR_NAME
".1", ev64360_fixup_mpsc_pdata
},
314 #if defined(CONFIG_MV643XX_ETH)
315 { MV643XX_ETH_NAME
".0", ev64360_fixup_eth_pdata
},
316 { MV643XX_ETH_NAME
".1", ev64360_fixup_eth_pdata
},
317 { MV643XX_ETH_NAME
".2", ev64360_fixup_eth_pdata
},
320 struct platform_device
*pdev
;
323 if (dev
&& dev
->bus_id
)
324 for (i
=0; i
<ARRAY_SIZE(dev_map
); i
++)
325 if (!strncmp(dev
->bus_id
, dev_map
[i
].bus_id
,
328 pdev
= container_of(dev
,
329 struct platform_device
, dev
);
330 dev_map
[i
].rtn(pdev
);
336 #ifdef CONFIG_MTD_PHYSMAP
345 * FLASH Amount: 0xff000000 - 0xffffffff
346 * ------------- -----------------------
347 * Reserved: 0xff000000 - 0xff03ffff
348 * JFFS2 file system: 0xff040000 - 0xffefffff
349 * U-boot: 0xfff00000 - 0xffffffff
352 ev64360_setup_mtd(void)
356 static struct mtd_partition
*ptbl
;
358 size
= ev64360_flash_size_0
+ ev64360_flash_size_1
;
364 if ((ptbl
= kmalloc(ptbl_entries
* sizeof(struct mtd_partition
),
365 GFP_KERNEL
)) == NULL
) {
367 printk(KERN_WARNING
"Can't alloc MTD partition table\n");
370 memset(ptbl
, 0, ptbl_entries
* sizeof(struct mtd_partition
));
372 ptbl
[0].name
= "reserved";
374 ptbl
[0].size
= EV64360_MTD_RESERVED_SIZE
;
375 ptbl
[1].name
= "jffs2";
376 ptbl
[1].offset
= EV64360_MTD_RESERVED_SIZE
;
377 ptbl
[1].size
= EV64360_MTD_JFFS2_SIZE
;
378 ptbl
[2].name
= "U-BOOT";
379 ptbl
[2].offset
= EV64360_MTD_RESERVED_SIZE
+ EV64360_MTD_JFFS2_SIZE
;
380 ptbl
[2].size
= EV64360_MTD_UBOOT_SIZE
;
382 physmap_map
.size
= size
;
383 physmap_set_partitions(ptbl
, ptbl_entries
);
387 arch_initcall(ev64360_setup_mtd
);
391 ev64360_restart(char *cmd
)
393 ulong i
= 0xffffffff;
394 volatile unsigned char * rtc_base
= ioremap(EV64360_RTC_WINDOW_BASE
,0x4000);
396 /* issue hard reset */
397 rtc_base
[0xf] = 0x80;
398 rtc_base
[0xc] = 0x00;
399 rtc_base
[0xd] = 0x01;
400 rtc_base
[0xf] = 0x83;
403 panic("restart failed\n");
414 ev64360_power_off(void)
421 ev64360_show_cpuinfo(struct seq_file
*m
)
423 seq_printf(m
, "vendor\t\t: " BOARD_VENDOR
"\n");
424 seq_printf(m
, "machine\t\t: " BOARD_MACHINE
"\n");
425 seq_printf(m
, "bus speed\t: %dMHz\n", ev64360_bus_frequency
/1000/1000);
431 ev64360_calibrate_decr(void)
435 freq
= ev64360_bus_frequency
/ 4;
437 printk(KERN_INFO
"time_init: decrementer frequency = %lu.%.6lu MHz\n",
438 (long)freq
/ 1000000, (long)freq
% 1000000);
440 tb_ticks_per_jiffy
= freq
/ HZ
;
441 tb_to_us
= mulhwu_scale_factor(freq
, 1000000);
445 ev64360_find_end_of_memory(void)
447 return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE
,
448 MV64x60_TYPE_MV64360
);
452 ev64360_set_bat(void)
455 mtspr(SPRN_DBAT2U
, 0xf0001ffe);
456 mtspr(SPRN_DBAT2L
, 0xf000002a);
460 #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
464 io_block_mapping(CONFIG_MV64X60_NEW_BASE
, \
465 CONFIG_MV64X60_NEW_BASE
, \
466 0x00020000, _PAGE_IO
);
471 platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
472 unsigned long r6
, unsigned long r7
)
474 parse_bootinfo(find_bootinfo());
476 /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer)
477 * are non-zero, then we should use the board info from the bd_t
478 * structure and the cmdline pointed to by r6 instead of the
479 * information from birecs, if any. Otherwise, use the information
480 * from birecs as discovered by the preceeding call to
481 * parse_bootinfo(). This rule should work with both PPCBoot, which
482 * uses a bd_t board info structure, and the kernel boot wrapper,
486 /* copy board info structure */
487 memcpy( (void *)__res
,(void *)(r3
+KERNELBASE
), sizeof(bd_t
) );
488 /* copy command line */
489 *(char *)(r7
+KERNELBASE
) = 0;
490 strcpy(cmd_line
, (char *)(r6
+KERNELBASE
));
496 ppc_md
.setup_arch
= ev64360_setup_arch
;
497 ppc_md
.show_cpuinfo
= ev64360_show_cpuinfo
;
498 ppc_md
.init_IRQ
= mv64360_init_irq
;
499 ppc_md
.get_irq
= mv64360_get_irq
;
500 ppc_md
.restart
= ev64360_restart
;
501 ppc_md
.power_off
= ev64360_power_off
;
502 ppc_md
.halt
= ev64360_halt
;
503 ppc_md
.find_end_of_memory
= ev64360_find_end_of_memory
;
506 ppc_md
.time_init
= todc_time_init
;
507 ppc_md
.set_rtc_time
= todc_set_rtc_time
;
508 ppc_md
.get_rtc_time
= todc_get_rtc_time
;
509 ppc_md
.nvram_read_val
= todc_direct_read_val
;
510 ppc_md
.nvram_write_val
= todc_direct_write_val
;
511 ppc_md
.calibrate_decr
= ev64360_calibrate_decr
;
513 #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
514 ppc_md
.setup_io_mappings
= ev64360_map_io
;
515 ppc_md
.progress
= mv64x60_mpsc_progress
;
516 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE
);
519 #if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
520 platform_notify
= ev64360_platform_notify
;
523 ev64360_set_bat(); /* Need for ev64360_find_end_of_memory and progress */