2 * Board setup routines for the Sky Computers HDPU Compute Blade.
4 * Written by Brian Waite <waite@skycomputers.com>
6 * Based on code done by - Mark A. Greer <mgreer@mvista.com>
7 * Rabeeh Khoury - rabeeh@galileo.co.il
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
16 #include <linux/pci.h>
17 #include <linux/delay.h>
18 #include <linux/irq.h>
19 #include <linux/ide.h>
20 #include <linux/seq_file.h>
21 #include <linux/platform_device.h>
23 #include <linux/initrd.h>
24 #include <linux/root_dev.h>
25 #include <linux/smp.h>
28 #include <asm/machdep.h>
30 #include <asm/mv64x60.h>
31 #include <asm/ppcboot.h>
32 #include <platforms/hdpu.h>
33 #include <linux/mv643xx.h>
34 #include <linux/hdpu_features.h>
35 #include <linux/device.h>
36 #include <linux/mtd/physmap.h>
38 #define BOARD_VENDOR "Sky Computers"
39 #define BOARD_MACHINE "HDPU-CB-A"
42 int ppcboot_bd_valid
= 0;
44 static mv64x60_handle_t bh
;
46 extern char cmd_line
[];
48 unsigned long hdpu_find_end_of_memory(void);
49 void hdpu_mpsc_progress(char *s
, unsigned short hex
);
50 void hdpu_heartbeat(void);
52 static void parse_bootinfo(unsigned long r3
,
53 unsigned long r4
, unsigned long r5
,
54 unsigned long r6
, unsigned long r7
);
55 static void hdpu_set_l1pe(void);
56 static void hdpu_cpustate_set(unsigned char new_state
);
58 static DEFINE_SPINLOCK(timebase_lock
);
59 static unsigned int timebase_upper
= 0, timebase_lower
= 0;
60 extern int smp_tb_synchronized
;
62 void __devinit
hdpu_tben_give(void);
63 void __devinit
hdpu_tben_take(void);
67 hdpu_map_irq(struct pci_dev
*dev
, unsigned char idsel
, unsigned char pin
)
69 struct pci_controller
*hose
= pci_bus_to_hose(dev
->bus
->number
);
71 if (hose
->index
== 0) {
72 static char pci_irq_table
[][4] = {
73 {HDPU_PCI_0_IRQ
, 0, 0, 0},
74 {HDPU_PCI_0_IRQ
, 0, 0, 0},
77 const long min_idsel
= 1, max_idsel
= 2, irqs_per_slot
= 4;
78 return PCI_IRQ_TABLE_LOOKUP
;
80 static char pci_irq_table
[][4] = {
81 {HDPU_PCI_1_IRQ
, 0, 0, 0},
84 const long min_idsel
= 1, max_idsel
= 1, irqs_per_slot
= 4;
85 return PCI_IRQ_TABLE_LOOKUP
;
89 static void __init
hdpu_intr_setup(void)
91 mv64x60_write(&bh
, MV64x60_GPP_IO_CNTL
,
92 (1 | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
93 (1 << 6) | (1 << 7) | (1 << 12) | (1 << 16) |
94 (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21) |
95 (1 << 22) | (1 << 23) | (1 << 24) | (1 << 25) |
96 (1 << 26) | (1 << 27) | (1 << 28) | (1 << 29)));
98 /* XXXX Erranum FEr PCI-#8 */
99 mv64x60_clr_bits(&bh
, MV64x60_PCI0_CMD
, (1 << 5) | (1 << 9));
100 mv64x60_clr_bits(&bh
, MV64x60_PCI1_CMD
, (1 << 5) | (1 << 9));
103 * Dismiss and then enable interrupt on GPP interrupt cause
106 mv64x60_write(&bh
, MV64x60_GPP_INTR_CAUSE
, ~((1 << 8) | (1 << 13)));
107 mv64x60_set_bits(&bh
, MV64x60_GPP_INTR_MASK
, (1 << 8) | (1 << 13));
110 * Dismiss and then enable interrupt on CPU #0 high cause reg
111 * BIT25 summarizes GPP interrupts 8-15
113 mv64x60_set_bits(&bh
, MV64360_IC_CPU0_INTR_MASK_HI
, (1 << 25));
116 static void __init
hdpu_setup_peripherals(void)
120 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2BOOT_WIN
,
121 HDPU_EMB_FLASH_BASE
, HDPU_EMB_FLASH_SIZE
, 0);
122 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2BOOT_WIN
);
124 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_0_WIN
,
125 HDPU_TBEN_BASE
, HDPU_TBEN_SIZE
, 0);
126 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_0_WIN
);
128 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_1_WIN
,
129 HDPU_NEXUS_ID_BASE
, HDPU_NEXUS_ID_SIZE
, 0);
130 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_1_WIN
);
132 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2SRAM_WIN
,
133 HDPU_INTERNAL_SRAM_BASE
,
134 HDPU_INTERNAL_SRAM_SIZE
, 0);
135 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2SRAM_WIN
);
137 bh
.ci
->disable_window_32bit(&bh
, MV64x60_ENET2MEM_4_WIN
);
138 mv64x60_set_32bit_window(&bh
, MV64x60_ENET2MEM_4_WIN
, 0, 0, 0);
140 mv64x60_clr_bits(&bh
, MV64x60_PCI0_PCI_DECODE_CNTL
, (1 << 3));
141 mv64x60_clr_bits(&bh
, MV64x60_PCI1_PCI_DECODE_CNTL
, (1 << 3));
142 mv64x60_clr_bits(&bh
, MV64x60_TIMR_CNTR_0_3_CNTL
,
143 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)));
145 /* Enable pipelining */
146 mv64x60_set_bits(&bh
, MV64x60_CPU_CONFIG
, (1 << 13));
147 /* Enable Snoop Pipelining */
148 mv64x60_set_bits(&bh
, MV64360_D_UNIT_CONTROL_HIGH
, (1 << 24));
151 * Change DRAM read buffer assignment.
152 * Assign read buffer 0 dedicated only for CPU,
153 * and the rest read buffer 1.
155 val
= mv64x60_read(&bh
, MV64360_SDRAM_CONFIG
);
156 val
= val
& 0x03ffffff;
157 val
= val
| 0xf8000000;
158 mv64x60_write(&bh
, MV64360_SDRAM_CONFIG
, val
);
161 * Configure internal SRAM -
162 * Cache coherent write back, if CONFIG_MV64360_SRAM_CACHE_COHERENT set
164 * Parity error propagation
165 * Arbitration not parked for CPU only
166 * Other bits are reserved.
168 #ifdef CONFIG_MV64360_SRAM_CACHE_COHERENT
169 mv64x60_write(&bh
, MV64360_SRAM_CONFIG
, 0x001600b2);
171 mv64x60_write(&bh
, MV64360_SRAM_CONFIG
, 0x001600b0);
177 static void __init
hdpu_setup_bridge(void)
179 struct mv64x60_setup_info si
;
182 memset(&si
, 0, sizeof(si
));
184 si
.phys_reg_base
= HDPU_BRIDGE_REG_BASE
;
185 si
.pci_0
.enable_bus
= 1;
186 si
.pci_0
.pci_io
.cpu_base
= HDPU_PCI0_IO_START_PROC_ADDR
;
187 si
.pci_0
.pci_io
.pci_base_hi
= 0;
188 si
.pci_0
.pci_io
.pci_base_lo
= HDPU_PCI0_IO_START_PCI_ADDR
;
189 si
.pci_0
.pci_io
.size
= HDPU_PCI0_IO_SIZE
;
190 si
.pci_0
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
191 si
.pci_0
.pci_mem
[0].cpu_base
= HDPU_PCI0_MEM_START_PROC_ADDR
;
192 si
.pci_0
.pci_mem
[0].pci_base_hi
= HDPU_PCI0_MEM_START_PCI_HI_ADDR
;
193 si
.pci_0
.pci_mem
[0].pci_base_lo
= HDPU_PCI0_MEM_START_PCI_LO_ADDR
;
194 si
.pci_0
.pci_mem
[0].size
= HDPU_PCI0_MEM_SIZE
;
195 si
.pci_0
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
196 si
.pci_0
.pci_cmd_bits
= 0;
197 si
.pci_0
.latency_timer
= 0x80;
199 si
.pci_1
.enable_bus
= 1;
200 si
.pci_1
.pci_io
.cpu_base
= HDPU_PCI1_IO_START_PROC_ADDR
;
201 si
.pci_1
.pci_io
.pci_base_hi
= 0;
202 si
.pci_1
.pci_io
.pci_base_lo
= HDPU_PCI1_IO_START_PCI_ADDR
;
203 si
.pci_1
.pci_io
.size
= HDPU_PCI1_IO_SIZE
;
204 si
.pci_1
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
205 si
.pci_1
.pci_mem
[0].cpu_base
= HDPU_PCI1_MEM_START_PROC_ADDR
;
206 si
.pci_1
.pci_mem
[0].pci_base_hi
= HDPU_PCI1_MEM_START_PCI_HI_ADDR
;
207 si
.pci_1
.pci_mem
[0].pci_base_lo
= HDPU_PCI1_MEM_START_PCI_LO_ADDR
;
208 si
.pci_1
.pci_mem
[0].size
= HDPU_PCI1_MEM_SIZE
;
209 si
.pci_1
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
210 si
.pci_1
.pci_cmd_bits
= 0;
211 si
.pci_1
.latency_timer
= 0x80;
213 for (i
= 0; i
< MV64x60_CPU2MEM_WINDOWS
; i
++) {
214 #if defined(CONFIG_NOT_COHERENT_CACHE)
215 si
.cpu_prot_options
[i
] = 0;
216 si
.enet_options
[i
] = MV64360_ENET2MEM_SNOOP_NONE
;
217 si
.mpsc_options
[i
] = MV64360_MPSC2MEM_SNOOP_NONE
;
218 si
.idma_options
[i
] = MV64360_IDMA2MEM_SNOOP_NONE
;
220 si
.pci_1
.acc_cntl_options
[i
] =
221 MV64360_PCI_ACC_CNTL_SNOOP_NONE
|
222 MV64360_PCI_ACC_CNTL_SWAP_NONE
|
223 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES
|
224 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES
;
226 si
.pci_0
.acc_cntl_options
[i
] =
227 MV64360_PCI_ACC_CNTL_SNOOP_NONE
|
228 MV64360_PCI_ACC_CNTL_SWAP_NONE
|
229 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES
|
230 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES
;
233 si
.cpu_prot_options
[i
] = 0;
234 si
.enet_options
[i
] = MV64360_ENET2MEM_SNOOP_WB
; /* errata */
235 si
.mpsc_options
[i
] = MV64360_MPSC2MEM_SNOOP_WB
; /* errata */
236 si
.idma_options
[i
] = MV64360_IDMA2MEM_SNOOP_WB
; /* errata */
238 si
.pci_0
.acc_cntl_options
[i
] =
239 MV64360_PCI_ACC_CNTL_SNOOP_WB
|
240 MV64360_PCI_ACC_CNTL_SWAP_NONE
|
241 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES
|
242 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES
;
244 si
.pci_1
.acc_cntl_options
[i
] =
245 MV64360_PCI_ACC_CNTL_SNOOP_WB
|
246 MV64360_PCI_ACC_CNTL_SWAP_NONE
|
247 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES
|
248 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES
;
252 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
| CPUSTATE_KERNEL_INIT_PCI
);
254 /* Lookup PCI host bridges */
255 mv64x60_init(&bh
, &si
);
256 pci_dram_offset
= 0; /* System mem at same addr on PCI & cpu bus */
257 ppc_md
.pci_swizzle
= common_swizzle
;
258 ppc_md
.pci_map_irq
= hdpu_map_irq
;
260 mv64x60_set_bus(&bh
, 0, 0);
261 bh
.hose_a
->first_busno
= 0;
262 bh
.hose_a
->last_busno
= 0xff;
263 bh
.hose_a
->last_busno
= pciauto_bus_scan(bh
.hose_a
, 0);
265 bh
.hose_b
->first_busno
= bh
.hose_a
->last_busno
+ 1;
266 mv64x60_set_bus(&bh
, 1, bh
.hose_b
->first_busno
);
267 bh
.hose_b
->last_busno
= 0xff;
268 bh
.hose_b
->last_busno
= pciauto_bus_scan(bh
.hose_b
,
269 bh
.hose_b
->first_busno
);
271 ppc_md
.pci_exclude_device
= mv64x60_pci_exclude_device
;
273 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
| CPUSTATE_KERNEL_INIT_REG
);
275 * Enabling of PCI internal-vs-external arbitration
276 * is a platform- and errata-dependent decision.
281 #if defined(CONFIG_SERIAL_MPSC_CONSOLE)
282 static void __init
hdpu_early_serial_map(void)
285 static char first_time
= 1;
287 #if defined(CONFIG_KGDB_TTYS0)
289 #elif defined(CONFIG_KGDB_TTYS1)
292 #error "Invalid kgdb_tty port"
296 gt_early_mpsc_init(KGDB_PORT
,
297 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
);
306 static void hdpu_init2(void)
311 #if defined(CONFIG_MV643XX_ETH)
312 static void __init
hdpu_fixup_eth_pdata(struct platform_device
*pd
)
315 struct mv643xx_eth_platform_data
*eth_pd
;
316 eth_pd
= pd
->dev
.platform_data
;
318 eth_pd
->force_phy_addr
= 1;
319 eth_pd
->phy_addr
= pd
->id
;
320 eth_pd
->speed
= SPEED_100
;
321 eth_pd
->duplex
= DUPLEX_FULL
;
322 eth_pd
->tx_queue_size
= 400;
323 eth_pd
->rx_queue_size
= 800;
327 static void __init
hdpu_fixup_mpsc_pdata(struct platform_device
*pd
)
330 struct mpsc_pdata
*pdata
;
332 pdata
= (struct mpsc_pdata
*)pd
->dev
.platform_data
;
334 pdata
->max_idle
= 40;
335 if (ppcboot_bd_valid
)
336 pdata
->default_baud
= ppcboot_bd
.bi_baudrate
;
338 pdata
->default_baud
= HDPU_DEFAULT_BAUD
;
339 pdata
->brg_clk_src
= HDPU_MPSC_CLK_SRC
;
340 pdata
->brg_clk_freq
= HDPU_MPSC_CLK_FREQ
;
343 #if defined(CONFIG_HDPU_FEATURES)
344 static void __init
hdpu_fixup_cpustate_pdata(struct platform_device
*pd
)
346 struct platform_device
*pds
[1];
348 mv64x60_pd_fixup(&bh
, pds
, 1);
352 static int hdpu_platform_notify(struct device
*dev
)
356 void ((*rtn
) (struct platform_device
* pdev
));
359 MPSC_CTLR_NAME
".0", hdpu_fixup_mpsc_pdata
},
360 #if defined(CONFIG_MV643XX_ETH)
362 MV643XX_ETH_NAME
".0", hdpu_fixup_eth_pdata
},
364 #if defined(CONFIG_HDPU_FEATURES)
366 HDPU_CPUSTATE_NAME
".0", hdpu_fixup_cpustate_pdata
},
369 struct platform_device
*pdev
;
372 if (dev
&& dev
->bus_id
)
373 for (i
= 0; i
< ARRAY_SIZE(dev_map
); i
++)
374 if (!strncmp(dev
->bus_id
, dev_map
[i
].bus_id
,
377 pdev
= container_of(dev
,
378 struct platform_device
,
380 dev_map
[i
].rtn(pdev
);
386 static void __init
hdpu_setup_arch(void)
389 ppc_md
.progress("hdpu_setup_arch: enter", 0);
390 #ifdef CONFIG_BLK_DEV_INITRD
392 ROOT_DEV
= Root_RAM0
;
395 #ifdef CONFIG_ROOT_NFS
398 ROOT_DEV
= Root_SDA2
;
401 ppc_md
.heartbeat
= hdpu_heartbeat
;
403 ppc_md
.heartbeat_reset
= HZ
;
404 ppc_md
.heartbeat_count
= 1;
407 ppc_md
.progress("hdpu_setup_arch: Enabling L2 cache", 0);
409 /* Enable L1 Parity Bits */
412 /* Enable L2 and L3 caches (if 745x) */
413 _set_L2CR(0x80080000);
416 ppc_md
.progress("hdpu_setup_arch: enter", 0);
420 hdpu_setup_peripherals();
422 #ifdef CONFIG_SERIAL_MPSC_CONSOLE
423 hdpu_early_serial_map();
426 printk("SKY HDPU Compute Blade \n");
429 ppc_md
.progress("hdpu_setup_arch: exit", 0);
431 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
| CPUSTATE_KERNEL_OK
);
434 static void __init
hdpu_init_irq(void)
439 static void __init
hdpu_set_l1pe()
442 asm volatile ("mfspr %0, 1011":"=r" (ictrl
):);
443 ictrl
|= ICTRL_EICE
| ICTRL_EDC
| ICTRL_EICP
;
444 asm volatile ("mtspr 1011, %0"::"r" (ictrl
));
448 * Set BAT 1 to map 0xf1000000 to end of physical memory space.
450 static __inline__
void hdpu_set_bat(void)
453 mtspr(SPRN_DBAT1U
, 0xf10001fe);
454 mtspr(SPRN_DBAT1L
, 0xf100002a);
460 unsigned long __init
hdpu_find_end_of_memory(void)
462 return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE
,
463 MV64x60_TYPE_MV64360
);
466 static void hdpu_reset_board(void)
468 volatile int infinite
= 1;
470 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
| CPUSTATE_KERNEL_RESET
);
474 /* Clear all the LEDs */
475 mv64x60_write(&bh
, MV64x60_GPP_VALUE_CLR
, ((1 << 4) |
476 (1 << 5) | (1 << 6)));
478 /* disable and invalidate the L2 cache */
482 /* flush and disable L1 I/D cache */
491 "isync\n" "sync\n" "mtspr 1008,5\n" "isync\n" "sync\n");
493 /* Hit the reset bit */
494 mv64x60_write(&bh
, MV64x60_GPP_VALUE_CLR
, (1 << 3));
502 static void hdpu_restart(char *cmd
)
504 volatile ulong i
= 10000000;
509 panic("restart failed\n");
512 static void hdpu_halt(void)
516 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
| CPUSTATE_KERNEL_HALT
);
518 /* Clear all the LEDs */
519 mv64x60_write(&bh
, MV64x60_GPP_VALUE_CLR
, ((1 << 4) | (1 << 5) |
525 static void hdpu_power_off(void)
531 static int hdpu_show_cpuinfo(struct seq_file
*m
)
535 pvid
= mfspr(SPRN_PVR
);
536 seq_printf(m
, "vendor\t\t: Sky Computers\n");
537 seq_printf(m
, "machine\t\t: HDPU Compute Blade\n");
538 seq_printf(m
, "PVID\t\t: 0x%x, vendor: %s\n",
539 pvid
, (pvid
& (1 << 15) ? "IBM" : "Motorola"));
544 static void __init
hdpu_calibrate_decr(void)
548 if (ppcboot_bd_valid
)
549 freq
= ppcboot_bd
.bi_busfreq
/ 4;
553 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
554 freq
/ 1000000, freq
% 1000000);
556 tb_ticks_per_jiffy
= freq
/ HZ
;
557 tb_to_us
= mulhwu_scale_factor(freq
, 1000000);
562 static void parse_bootinfo(unsigned long r3
,
563 unsigned long r4
, unsigned long r5
,
564 unsigned long r6
, unsigned long r7
)
567 char *cmdline_start
= NULL
;
571 if ((r3
& 0xf0000000) == 0)
573 if ((r3
& 0xf0000000) == KERNELBASE
) {
576 memcpy(&ppcboot_bd
, bd
, sizeof(ppcboot_bd
));
577 ppcboot_bd_valid
= 1;
580 #ifdef CONFIG_BLK_DEV_INITRD
581 if (r4
&& r5
&& r5
> r4
) {
582 if ((r4
& 0xf0000000) == 0)
584 if ((r5
& 0xf0000000) == 0)
586 if ((r4
& 0xf0000000) == KERNELBASE
) {
589 initrd_below_start_ok
= 1;
592 #endif /* CONFIG_BLK_DEV_INITRD */
594 if (r6
&& r7
&& r7
> r6
) {
595 if ((r6
& 0xf0000000) == 0)
597 if ((r7
& 0xf0000000) == 0)
599 if ((r6
& 0xf0000000) == KERNELBASE
) {
600 cmdline_start
= (void *)r6
;
601 cmdline_len
= (r7
- r6
);
602 strncpy(cmd_line
, cmdline_start
, cmdline_len
);
607 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
609 hdpu_ide_request_region(ide_ioreg_t from
, unsigned int extent
, const char *name
)
611 request_region(from
, extent
, name
);
615 static void hdpu_ide_release_region(ide_ioreg_t from
, unsigned int extent
)
617 release_region(from
, extent
);
622 hdpu_ide_pci_init_hwif_ports(hw_regs_t
* hw
, ide_ioreg_t data_port
,
623 ide_ioreg_t ctrl_port
, int *irq
)
627 pci_for_each_dev(dev
) {
628 if (((dev
->class >> 8) == PCI_CLASS_STORAGE_IDE
) ||
629 ((dev
->class >> 8) == PCI_CLASS_STORAGE_RAID
)) {
642 void hdpu_heartbeat(void)
644 if (mv64x60_read(&bh
, MV64x60_GPP_VALUE
) & (1 << 5))
645 mv64x60_write(&bh
, MV64x60_GPP_VALUE_CLR
, (1 << 5));
647 mv64x60_write(&bh
, MV64x60_GPP_VALUE_SET
, (1 << 5));
649 ppc_md
.heartbeat_count
= ppc_md
.heartbeat_reset
;
653 static void __init
hdpu_map_io(void)
655 io_block_mapping(0xf1000000, 0xf1000000, 0x20000, _PAGE_IO
);
659 char hdpu_smp0
[] = "SMP Cpu #0";
660 char hdpu_smp1
[] = "SMP Cpu #1";
662 static irqreturn_t
hdpu_smp_cpu0_int_handler(int irq
, void *dev_id
)
664 volatile unsigned int doorbell
;
666 doorbell
= mv64x60_read(&bh
, MV64360_CPU0_DOORBELL
);
668 /* Ack the doorbell interrupts */
669 mv64x60_write(&bh
, MV64360_CPU0_DOORBELL_CLR
, doorbell
);
686 static irqreturn_t
hdpu_smp_cpu1_int_handler(int irq
, void *dev_id
)
688 volatile unsigned int doorbell
;
690 doorbell
= mv64x60_read(&bh
, MV64360_CPU1_DOORBELL
);
692 /* Ack the doorbell interrupts */
693 mv64x60_write(&bh
, MV64360_CPU1_DOORBELL_CLR
, doorbell
);
710 static void smp_hdpu_CPU_two(void)
716 "mtspr 26, 3\n" "li 4,0\n" "mtspr 27,4\n" "rfi");
720 static int smp_hdpu_probe(void)
725 cpu_count_reg
= ioremap(HDPU_NEXUS_ID_BASE
, HDPU_NEXUS_ID_SIZE
);
727 num_cpus
= (*cpu_count_reg
>> 20) & 0x3;
728 iounmap(cpu_count_reg
);
731 /* Validate the bits in the CPLD. If we could not map the reg, return 2.
732 * If the register reported 0 or 3, return 2.
733 * Older CPLD revisions set these bits to all ones (val = 3).
735 if ((num_cpus
< 1) || (num_cpus
> 2)) {
737 ("Unable to determine the number of processors %d . deafulting to 2.\n",
745 smp_hdpu_message_pass(int target
, int msg
)
748 printk("SMP %d: smp_message_pass: unknown msg %d\n",
749 smp_processor_id(), msg
);
754 mv64x60_write(&bh
, MV64360_CPU0_DOORBELL
, 1 << msg
);
755 mv64x60_write(&bh
, MV64360_CPU1_DOORBELL
, 1 << msg
);
757 case MSG_ALL_BUT_SELF
:
758 if (smp_processor_id())
759 mv64x60_write(&bh
, MV64360_CPU0_DOORBELL
, 1 << msg
);
761 mv64x60_write(&bh
, MV64360_CPU1_DOORBELL
, 1 << msg
);
765 mv64x60_write(&bh
, MV64360_CPU0_DOORBELL
, 1 << msg
);
767 mv64x60_write(&bh
, MV64360_CPU1_DOORBELL
, 1 << msg
);
772 static void smp_hdpu_kick_cpu(int nr
)
774 volatile unsigned int *bootaddr
;
777 ppc_md
.progress("smp_hdpu_kick_cpu", 0);
779 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
| CPUSTATE_KERNEL_CPU1_KICK
);
781 /* Disable BootCS. Must also reduce the windows size to zero. */
782 bh
.ci
->disable_window_32bit(&bh
, MV64x60_CPU2BOOT_WIN
);
783 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2BOOT_WIN
, 0, 0, 0);
785 bootaddr
= ioremap(HDPU_INTERNAL_SRAM_BASE
, HDPU_INTERNAL_SRAM_SIZE
);
788 ppc_md
.progress("smp_hdpu_kick_cpu: ioremap failed", 0);
792 memcpy((void *)(bootaddr
+ 0x40), (void *)&smp_hdpu_CPU_two
, 0x20);
794 /* map SRAM to 0xfff00000 */
795 bh
.ci
->disable_window_32bit(&bh
, MV64x60_CPU2SRAM_WIN
);
797 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2SRAM_WIN
,
798 0xfff00000, HDPU_INTERNAL_SRAM_SIZE
, 0);
799 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2SRAM_WIN
);
801 /* Enable CPU1 arbitration */
802 mv64x60_clr_bits(&bh
, MV64x60_CPU_MASTER_CNTL
, (1 << 9));
805 * Wait 100mSecond until other CPU has reached __secondary_start.
806 * When it reaches, it is permittable to rever the SRAM mapping etc...
809 *(unsigned long *)KERNELBASE
= nr
;
810 asm volatile ("dcbf 0,%0"::"r" (KERNELBASE
):"memory");
814 /* Set up window for internal sram (256KByte insize) */
815 bh
.ci
->disable_window_32bit(&bh
, MV64x60_CPU2SRAM_WIN
);
816 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2SRAM_WIN
,
817 HDPU_INTERNAL_SRAM_BASE
,
818 HDPU_INTERNAL_SRAM_SIZE
, 0);
819 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2SRAM_WIN
);
821 * Set up windows for embedded FLASH (using boot CS window).
824 bh
.ci
->disable_window_32bit(&bh
, MV64x60_CPU2BOOT_WIN
);
825 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2BOOT_WIN
,
826 HDPU_EMB_FLASH_BASE
, HDPU_EMB_FLASH_SIZE
, 0);
827 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2BOOT_WIN
);
830 static void smp_hdpu_setup_cpu(int cpu_nr
)
834 ppc_md
.progress("smp_hdpu_setup_cpu 0", 0);
835 mv64x60_write(&bh
, MV64360_CPU0_DOORBELL_CLR
, 0xff);
836 mv64x60_write(&bh
, MV64360_CPU0_DOORBELL_MASK
, 0xff);
837 request_irq(60, hdpu_smp_cpu0_int_handler
,
838 IRQF_DISABLED
, hdpu_smp0
, 0);
843 ppc_md
.progress("smp_hdpu_setup_cpu 1", 0);
845 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR
|
846 CPUSTATE_KERNEL_CPU1_OK
);
848 /* Enable L1 Parity Bits */
851 /* Enable L2 cache */
853 _set_L2CR(0x80080000);
855 mv64x60_write(&bh
, MV64360_CPU1_DOORBELL_CLR
, 0x0);
856 mv64x60_write(&bh
, MV64360_CPU1_DOORBELL_MASK
, 0xff);
857 request_irq(28, hdpu_smp_cpu1_int_handler
,
858 IRQF_DISABLED
, hdpu_smp1
, 0);
863 void __devinit
hdpu_tben_give()
865 volatile unsigned long *val
= 0;
867 /* By writing 0 to the TBEN_BASE, the timebases is frozen */
868 val
= ioremap(HDPU_TBEN_BASE
, 4);
872 spin_lock(&timebase_lock
);
873 timebase_upper
= get_tbu();
874 timebase_lower
= get_tbl();
875 spin_unlock(&timebase_lock
);
877 while (timebase_upper
|| timebase_lower
)
880 /* By writing 1 to the TBEN_BASE, the timebases is thawed */
888 void __devinit
hdpu_tben_take()
890 while (!(timebase_upper
|| timebase_lower
))
893 spin_lock(&timebase_lock
);
894 set_tb(timebase_upper
, timebase_lower
);
897 spin_unlock(&timebase_lock
);
900 static struct smp_ops_t hdpu_smp_ops
= {
901 .message_pass
= smp_hdpu_message_pass
,
902 .probe
= smp_hdpu_probe
,
903 .kick_cpu
= smp_hdpu_kick_cpu
,
904 .setup_cpu
= smp_hdpu_setup_cpu
,
905 .give_timebase
= hdpu_tben_give
,
906 .take_timebase
= hdpu_tben_take
,
908 #endif /* CONFIG_SMP */
911 platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
912 unsigned long r6
, unsigned long r7
)
914 parse_bootinfo(r3
, r4
, r5
, r6
, r7
);
918 ppc_md
.setup_arch
= hdpu_setup_arch
;
919 ppc_md
.init
= hdpu_init2
;
920 ppc_md
.show_cpuinfo
= hdpu_show_cpuinfo
;
921 ppc_md
.init_IRQ
= hdpu_init_irq
;
922 ppc_md
.get_irq
= mv64360_get_irq
;
923 ppc_md
.restart
= hdpu_restart
;
924 ppc_md
.power_off
= hdpu_power_off
;
925 ppc_md
.halt
= hdpu_halt
;
926 ppc_md
.find_end_of_memory
= hdpu_find_end_of_memory
;
927 ppc_md
.calibrate_decr
= hdpu_calibrate_decr
;
928 ppc_md
.setup_io_mappings
= hdpu_map_io
;
930 bh
.p_base
= CONFIG_MV64X60_NEW_BASE
;
931 bh
.v_base
= (unsigned long *)bh
.p_base
;
935 #if defined(CONFIG_SERIAL_TEXT_DEBUG)
936 ppc_md
.progress
= hdpu_mpsc_progress
; /* embedded UART */
937 mv64x60_progress_init(bh
.p_base
);
938 #endif /* CONFIG_SERIAL_TEXT_DEBUG */
941 smp_ops
= &hdpu_smp_ops
;
942 #endif /* CONFIG_SMP */
944 #if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
945 platform_notify
= hdpu_platform_notify
;
950 #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
951 /* SMP safe version of the serial text debug routine. Uses Semaphore 0 */
952 void hdpu_mpsc_progress(char *s
, unsigned short hex
)
954 while (mv64x60_read(&bh
, MV64360_WHO_AM_I
) !=
955 mv64x60_read(&bh
, MV64360_SEMAPHORE_0
)) {
957 mv64x60_mpsc_progress(s
, hex
);
958 mv64x60_write(&bh
, MV64360_SEMAPHORE_0
, 0xff);
962 static void hdpu_cpustate_set(unsigned char new_state
)
964 unsigned int state
= (new_state
<< 21);
965 mv64x60_write(&bh
, MV64x60_GPP_VALUE_CLR
, (0xff << 21));
966 mv64x60_write(&bh
, MV64x60_GPP_VALUE_CLR
, state
);
969 #ifdef CONFIG_MTD_PHYSMAP
970 static struct mtd_partition hdpu_partitions
[] = {
979 .offset
= 0x03400000,
982 .name
= "Kernel Image",
984 .offset
= 0x03C00000,
989 .offset
= 0x03EC0000,
994 .offset
= 0x03F00000,
999 static int __init
hdpu_setup_mtd(void)
1002 physmap_set_partitions(hdpu_partitions
, 5);
1006 arch_initcall(hdpu_setup_mtd
);
1009 #ifdef CONFIG_HDPU_FEATURES
1011 static struct resource hdpu_cpustate_resources
[] = {
1013 .name
= "addr base",
1014 .start
= MV64x60_GPP_VALUE_SET
,
1015 .end
= MV64x60_GPP_VALUE_CLR
+ 1,
1016 .flags
= IORESOURCE_MEM
,
1020 static struct resource hdpu_nexus_resources
[] = {
1022 .name
= "nexus register",
1023 .start
= HDPU_NEXUS_ID_BASE
,
1024 .end
= HDPU_NEXUS_ID_BASE
+ HDPU_NEXUS_ID_SIZE
,
1025 .flags
= IORESOURCE_MEM
,
1029 static struct platform_device hdpu_cpustate_device
= {
1030 .name
= HDPU_CPUSTATE_NAME
,
1032 .num_resources
= ARRAY_SIZE(hdpu_cpustate_resources
),
1033 .resource
= hdpu_cpustate_resources
,
1036 static struct platform_device hdpu_nexus_device
= {
1037 .name
= HDPU_NEXUS_NAME
,
1039 .num_resources
= ARRAY_SIZE(hdpu_nexus_resources
),
1040 .resource
= hdpu_nexus_resources
,
1043 static int __init
hdpu_add_pds(void)
1045 platform_device_register(&hdpu_cpustate_device
);
1046 platform_device_register(&hdpu_nexus_device
);
1050 arch_initcall(hdpu_add_pds
);