2 * arch/ppc/platforms/cpci690.c
4 * Board setup routines for the Force CPCI690 board.
6 * Author: Mark A. Greer <mgreer@mvista.com>
8 * 2003 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This programr
10 * is licensed "as is" without any warranty of any kind, whether express
13 #include <linux/config.h>
14 #include <linux/delay.h>
15 #include <linux/pci.h>
16 #include <linux/ide.h>
17 #include <linux/irq.h>
19 #include <linux/seq_file.h>
20 #include <linux/console.h>
21 #include <linux/initrd.h>
22 #include <linux/root_dev.h>
23 #include <linux/mv643xx.h>
24 #include <asm/bootinfo.h>
25 #include <asm/machdep.h>
28 #include <asm/mv64x60.h>
29 #include <platforms/cpci690.h>
31 #define BOARD_VENDOR "Force"
32 #define BOARD_MACHINE "CPCI690"
34 /* Set IDE controllers into Native mode? */
35 #define SET_PCI_IDE_NATIVE
37 static struct mv64x60_handle bh
;
38 static void __iomem
*cpci690_br_base
;
43 cpci690_map_irq(struct pci_dev
*dev
, unsigned char idsel
, unsigned char pin
)
45 struct pci_controller
*hose
= pci_bus_to_hose(dev
->bus
->number
);
47 if (hose
->index
== 0) {
48 static char pci_irq_table
[][4] =
50 * PCI IDSEL/INTPIN->INTLINE
54 { 90, 91, 88, 89 }, /* IDSEL 30/20 - Sentinel */
57 const long min_idsel
= 20, max_idsel
= 20, irqs_per_slot
= 4;
58 return PCI_IRQ_TABLE_LOOKUP
;
60 static char pci_irq_table
[][4] =
62 * PCI IDSEL/INTPIN->INTLINE
66 { 93, 94, 95, 92 }, /* IDSEL 28/18 - PMC slot 2 */
67 { 0, 0, 0, 0 }, /* IDSEL 29/19 - Not used */
68 { 94, 95, 92, 93 }, /* IDSEL 30/20 - PMC slot 1 */
71 const long min_idsel
= 18, max_idsel
= 20, irqs_per_slot
= 4;
72 return PCI_IRQ_TABLE_LOOKUP
;
76 #define GB (1024UL * 1024UL * 1024UL)
79 cpci690_get_bus_freq(void)
81 if (boot_mem_size
>= (1*GB
)) /* bus speed based on mem size */
87 static const unsigned int cpu_750xx
[32] = { /* 750FX & 750GX */
88 0, 0, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,/* 0-15*/
89 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 0 /*16-31*/
93 cpci690_get_cpu_freq(void)
95 unsigned long pll_cfg
;
97 pll_cfg
= (mfspr(SPRN_HID1
) & 0xf8000000) >> 27;
98 return cpci690_get_bus_freq() * cpu_750xx
[pll_cfg
]/2;
102 cpci690_setup_bridge(void)
104 struct mv64x60_setup_info si
;
107 memset(&si
, 0, sizeof(si
));
109 si
.phys_reg_base
= CONFIG_MV64X60_NEW_BASE
;
111 si
.pci_0
.enable_bus
= 1;
112 si
.pci_0
.pci_io
.cpu_base
= CPCI690_PCI0_IO_START_PROC_ADDR
;
113 si
.pci_0
.pci_io
.pci_base_hi
= 0;
114 si
.pci_0
.pci_io
.pci_base_lo
= CPCI690_PCI0_IO_START_PCI_ADDR
;
115 si
.pci_0
.pci_io
.size
= CPCI690_PCI0_IO_SIZE
;
116 si
.pci_0
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
117 si
.pci_0
.pci_mem
[0].cpu_base
= CPCI690_PCI0_MEM_START_PROC_ADDR
;
118 si
.pci_0
.pci_mem
[0].pci_base_hi
= CPCI690_PCI0_MEM_START_PCI_HI_ADDR
;
119 si
.pci_0
.pci_mem
[0].pci_base_lo
= CPCI690_PCI0_MEM_START_PCI_LO_ADDR
;
120 si
.pci_0
.pci_mem
[0].size
= CPCI690_PCI0_MEM_SIZE
;
121 si
.pci_0
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
122 si
.pci_0
.pci_cmd_bits
= 0;
123 si
.pci_0
.latency_timer
= 0x80;
125 si
.pci_1
.enable_bus
= 1;
126 si
.pci_1
.pci_io
.cpu_base
= CPCI690_PCI1_IO_START_PROC_ADDR
;
127 si
.pci_1
.pci_io
.pci_base_hi
= 0;
128 si
.pci_1
.pci_io
.pci_base_lo
= CPCI690_PCI1_IO_START_PCI_ADDR
;
129 si
.pci_1
.pci_io
.size
= CPCI690_PCI1_IO_SIZE
;
130 si
.pci_1
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
131 si
.pci_1
.pci_mem
[0].cpu_base
= CPCI690_PCI1_MEM_START_PROC_ADDR
;
132 si
.pci_1
.pci_mem
[0].pci_base_hi
= CPCI690_PCI1_MEM_START_PCI_HI_ADDR
;
133 si
.pci_1
.pci_mem
[0].pci_base_lo
= CPCI690_PCI1_MEM_START_PCI_LO_ADDR
;
134 si
.pci_1
.pci_mem
[0].size
= CPCI690_PCI1_MEM_SIZE
;
135 si
.pci_1
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
136 si
.pci_1
.pci_cmd_bits
= 0;
137 si
.pci_1
.latency_timer
= 0x80;
139 for (i
=0; i
<MV64x60_CPU2MEM_WINDOWS
; i
++) {
140 si
.cpu_prot_options
[i
] = 0;
141 si
.cpu_snoop_options
[i
] = GT64260_CPU_SNOOP_WB
;
142 si
.pci_0
.acc_cntl_options
[i
] =
143 GT64260_PCI_ACC_CNTL_DREADEN
|
144 GT64260_PCI_ACC_CNTL_RDPREFETCH
|
145 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH
|
146 GT64260_PCI_ACC_CNTL_RDMULPREFETCH
|
147 GT64260_PCI_ACC_CNTL_SWAP_NONE
|
148 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES
;
149 si
.pci_0
.snoop_options
[i
] = GT64260_PCI_SNOOP_WB
;
150 si
.pci_1
.acc_cntl_options
[i
] =
151 GT64260_PCI_ACC_CNTL_DREADEN
|
152 GT64260_PCI_ACC_CNTL_RDPREFETCH
|
153 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH
|
154 GT64260_PCI_ACC_CNTL_RDMULPREFETCH
|
155 GT64260_PCI_ACC_CNTL_SWAP_NONE
|
156 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES
;
157 si
.pci_1
.snoop_options
[i
] = GT64260_PCI_SNOOP_WB
;
160 /* Lookup PCI host bridges */
161 if (mv64x60_init(&bh
, &si
))
162 printk(KERN_ERR
"Bridge initialization failed.\n");
164 pci_dram_offset
= 0; /* System mem at same addr on PCI & cpu bus */
165 ppc_md
.pci_swizzle
= common_swizzle
;
166 ppc_md
.pci_map_irq
= cpci690_map_irq
;
167 ppc_md
.pci_exclude_device
= mv64x60_pci_exclude_device
;
169 mv64x60_set_bus(&bh
, 0, 0);
170 bh
.hose_a
->first_busno
= 0;
171 bh
.hose_a
->last_busno
= 0xff;
172 bh
.hose_a
->last_busno
= pciauto_bus_scan(bh
.hose_a
, 0);
174 bh
.hose_b
->first_busno
= bh
.hose_a
->last_busno
+ 1;
175 mv64x60_set_bus(&bh
, 1, bh
.hose_b
->first_busno
);
176 bh
.hose_b
->last_busno
= 0xff;
177 bh
.hose_b
->last_busno
= pciauto_bus_scan(bh
.hose_b
,
178 bh
.hose_b
->first_busno
);
182 cpci690_setup_peripherals(void)
184 /* Set up windows to CPLD, RTC/TODC, IPMI. */
185 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_0_WIN
, CPCI690_BR_BASE
,
187 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_0_WIN
);
188 cpci690_br_base
= ioremap(CPCI690_BR_BASE
, CPCI690_BR_SIZE
);
190 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_1_WIN
, CPCI690_TODC_BASE
,
191 CPCI690_TODC_SIZE
, 0);
192 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_1_WIN
);
193 TODC_INIT(TODC_TYPE_MK48T35
, 0, 0,
194 ioremap(CPCI690_TODC_BASE
, CPCI690_TODC_SIZE
), 8);
196 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_2_WIN
, CPCI690_IPMI_BASE
,
197 CPCI690_IPMI_SIZE
, 0);
198 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_2_WIN
);
200 mv64x60_set_bits(&bh
, MV64x60_PCI0_ARBITER_CNTL
, (1<<31));
201 mv64x60_set_bits(&bh
, MV64x60_PCI1_ARBITER_CNTL
, (1<<31));
203 mv64x60_set_bits(&bh
, MV64x60_CPU_MASTER_CNTL
, (1<<9)); /* Only 1 cpu */
206 * Turn off timer/counters. Not turning off watchdog timer because
207 * can't read its reg on the 64260A so don't know if we'll be enabling
210 mv64x60_clr_bits(&bh
, MV64x60_TIMR_CNTR_0_3_CNTL
,
211 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
212 mv64x60_clr_bits(&bh
, GT64260_TIMR_CNTR_4_7_CNTL
,
213 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
216 * Set MPSC Multiplex RMII
217 * NOTE: ethernet driver modifies bit 0 and 1
219 mv64x60_write(&bh
, GT64260_MPP_SERIAL_PORTS_MULTIPLEX
, 0x00001102);
221 #define GPP_EXTERNAL_INTERRUPTS \
222 ((1<<24) | (1<<25) | (1<<26) | (1<<27) | \
223 (1<<28) | (1<<29) | (1<<30) | (1<<31))
224 /* PCI interrupts are inputs */
225 mv64x60_clr_bits(&bh
, MV64x60_GPP_IO_CNTL
, GPP_EXTERNAL_INTERRUPTS
);
226 /* PCI interrupts are active low */
227 mv64x60_set_bits(&bh
, MV64x60_GPP_LEVEL_CNTL
, GPP_EXTERNAL_INTERRUPTS
);
229 /* Clear any pending interrupts for these inputs and enable them. */
230 mv64x60_write(&bh
, MV64x60_GPP_INTR_CAUSE
, ~GPP_EXTERNAL_INTERRUPTS
);
231 mv64x60_set_bits(&bh
, MV64x60_GPP_INTR_MASK
, GPP_EXTERNAL_INTERRUPTS
);
233 /* Route MPP interrupt inputs to GPP */
234 mv64x60_write(&bh
, MV64x60_MPP_CNTL_2
, 0x00000000);
235 mv64x60_write(&bh
, MV64x60_MPP_CNTL_3
, 0x00000000);
239 cpci690_setup_arch(void)
242 ppc_md
.progress("cpci690_setup_arch: enter", 0);
243 #ifdef CONFIG_BLK_DEV_INITRD
245 ROOT_DEV
= Root_RAM0
;
248 #ifdef CONFIG_ROOT_NFS
251 ROOT_DEV
= Root_SDA2
;
255 ppc_md
.progress("cpci690_setup_arch: Enabling L2 cache", 0);
257 /* Enable L2 and L3 caches (if 745x) */
258 _set_L2CR(_get_L2CR() | L2CR_L2E
);
259 _set_L3CR(_get_L3CR() | L3CR_L3E
);
262 ppc_md
.progress("cpci690_setup_arch: Initializing bridge", 0);
264 cpci690_setup_bridge(); /* set up PCI bridge(s) */
265 cpci690_setup_peripherals(); /* set up chip selects/GPP/MPP etc */
268 ppc_md
.progress("cpci690_setup_arch: bridge init complete", 0);
270 printk(KERN_INFO
"%s %s port (C) 2003 MontaVista Software, Inc. "
271 "(source@mvista.com)\n", BOARD_VENDOR
, BOARD_MACHINE
);
274 ppc_md
.progress("cpci690_setup_arch: exit", 0);
277 /* Platform device data fixup routines. */
278 #if defined(CONFIG_SERIAL_MPSC)
280 cpci690_fixup_mpsc_pdata(struct platform_device
*pdev
)
282 struct mpsc_pdata
*pdata
;
284 pdata
= (struct mpsc_pdata
*)pdev
->dev
.platform_data
;
286 pdata
->max_idle
= 40;
287 pdata
->default_baud
= CPCI690_MPSC_BAUD
;
288 pdata
->brg_clk_src
= CPCI690_MPSC_CLK_SRC
;
289 pdata
->brg_clk_freq
= cpci690_get_bus_freq();
293 cpci690_platform_notify(struct device
*dev
)
297 void ((*rtn
)(struct platform_device
*pdev
));
299 { MPSC_CTLR_NAME
".0", cpci690_fixup_mpsc_pdata
},
300 { MPSC_CTLR_NAME
".1", cpci690_fixup_mpsc_pdata
},
302 struct platform_device
*pdev
;
305 if (dev
&& dev
->bus_id
)
306 for (i
=0; i
<ARRAY_SIZE(dev_map
); i
++)
307 if (!strncmp(dev
->bus_id
, dev_map
[i
].bus_id
,
310 pdev
= container_of(dev
,
311 struct platform_device
, dev
);
312 dev_map
[i
].rtn(pdev
);
320 cpci690_reset_board(void)
325 out_8((cpci690_br_base
+ CPCI690_BR_SW_RESET
), 0x11);
328 panic("restart failed\n");
332 cpci690_restart(char *cmd
)
334 cpci690_reset_board();
345 cpci690_power_off(void)
352 cpci690_show_cpuinfo(struct seq_file
*m
)
356 seq_printf(m
, "cpu MHz\t\t: %d\n",
357 (cpci690_get_cpu_freq() + 500000) / 1000000);
358 seq_printf(m
, "bus MHz\t\t: %d\n",
359 (cpci690_get_bus_freq() + 500000) / 1000000);
360 seq_printf(m
, "vendor\t\t: " BOARD_VENDOR
"\n");
361 seq_printf(m
, "machine\t\t: " BOARD_MACHINE
"\n");
362 seq_printf(m
, "FPGA Revision\t: %d\n",
363 in_8(cpci690_br_base
+ CPCI690_BR_MEM_CTLR
) >> 5);
366 case MV64x60_TYPE_GT64260A
:
369 case MV64x60_TYPE_GT64260B
:
372 case MV64x60_TYPE_MV64360
:
375 case MV64x60_TYPE_MV64460
:
381 seq_printf(m
, "bridge type\t: %s\n", s
);
382 seq_printf(m
, "bridge rev\t: 0x%x\n", bh
.rev
);
383 #if defined(CONFIG_NOT_COHERENT_CACHE)
384 seq_printf(m
, "coherency\t: %s\n", "off");
386 seq_printf(m
, "coherency\t: %s\n", "on");
393 cpci690_calibrate_decr(void)
397 freq
= cpci690_get_bus_freq() / 4;
399 printk(KERN_INFO
"time_init: decrementer frequency = %lu.%.6lu MHz\n",
400 freq
/1000000, freq
%1000000);
402 tb_ticks_per_jiffy
= freq
/ HZ
;
403 tb_to_us
= mulhwu_scale_factor(freq
, 1000000);
406 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC)
410 io_block_mapping(CONFIG_MV64X60_NEW_BASE
, CONFIG_MV64X60_NEW_BASE
,
411 128 * 1024, _PAGE_IO
);
416 platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
417 unsigned long r6
, unsigned long r7
)
419 parse_bootinfo(find_bootinfo());
421 #ifdef CONFIG_BLK_DEV_INITRD
422 /* take care of initrd if we have one */
424 initrd_start
= r4
+ KERNELBASE
;
425 initrd_end
= r5
+ KERNELBASE
;
427 #endif /* CONFIG_BLK_DEV_INITRD */
431 ppc_md
.setup_arch
= cpci690_setup_arch
;
432 ppc_md
.show_cpuinfo
= cpci690_show_cpuinfo
;
433 ppc_md
.init_IRQ
= gt64260_init_irq
;
434 ppc_md
.get_irq
= gt64260_get_irq
;
435 ppc_md
.restart
= cpci690_restart
;
436 ppc_md
.power_off
= cpci690_power_off
;
437 ppc_md
.halt
= cpci690_halt
;
438 ppc_md
.time_init
= todc_time_init
;
439 ppc_md
.set_rtc_time
= todc_set_rtc_time
;
440 ppc_md
.get_rtc_time
= todc_get_rtc_time
;
441 ppc_md
.nvram_read_val
= todc_direct_read_val
;
442 ppc_md
.nvram_write_val
= todc_direct_write_val
;
443 ppc_md
.calibrate_decr
= cpci690_calibrate_decr
;
445 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC)
446 ppc_md
.setup_io_mappings
= cpci690_map_io
;
447 #ifdef CONFIG_SERIAL_TEXT_DEBUG
448 ppc_md
.progress
= mv64x60_mpsc_progress
;
449 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE
);
450 #endif /* CONFIG_SERIAL_TEXT_DEBUG */
451 #endif /* defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC) */
453 #if defined(CONFIG_SERIAL_MPSC)
454 platform_notify
= cpci690_platform_notify
;