2 * Board setup routines for the Force CPCI690 board.
4 * Author: Mark A. Greer <mgreer@mvista.com>
6 * 2003 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This programr
8 * is licensed "as is" without any warranty of any kind, whether express
11 #include <linux/delay.h>
12 #include <linux/pci.h>
13 #include <linux/ide.h>
14 #include <linux/irq.h>
16 #include <linux/seq_file.h>
17 #include <linux/console.h>
18 #include <linux/initrd.h>
19 #include <linux/root_dev.h>
20 #include <linux/mv643xx.h>
21 #include <linux/platform_device.h>
22 #include <asm/bootinfo.h>
23 #include <asm/machdep.h>
26 #include <asm/mv64x60.h>
27 #include <platforms/cpci690.h>
29 #define BOARD_VENDOR "Force"
30 #define BOARD_MACHINE "CPCI690"
32 /* Set IDE controllers into Native mode? */
33 #define SET_PCI_IDE_NATIVE
35 static struct mv64x60_handle bh
;
36 static void __iomem
*cpci690_br_base
;
41 cpci690_map_irq(struct pci_dev
*dev
, unsigned char idsel
, unsigned char pin
)
43 struct pci_controller
*hose
= pci_bus_to_hose(dev
->bus
->number
);
45 if (hose
->index
== 0) {
46 static char pci_irq_table
[][4] =
48 * PCI IDSEL/INTPIN->INTLINE
52 { 90, 91, 88, 89 }, /* IDSEL 30/20 - Sentinel */
55 const long min_idsel
= 20, max_idsel
= 20, irqs_per_slot
= 4;
56 return PCI_IRQ_TABLE_LOOKUP
;
58 static char pci_irq_table
[][4] =
60 * PCI IDSEL/INTPIN->INTLINE
64 { 93, 94, 95, 92 }, /* IDSEL 28/18 - PMC slot 2 */
65 { 0, 0, 0, 0 }, /* IDSEL 29/19 - Not used */
66 { 94, 95, 92, 93 }, /* IDSEL 30/20 - PMC slot 1 */
69 const long min_idsel
= 18, max_idsel
= 20, irqs_per_slot
= 4;
70 return PCI_IRQ_TABLE_LOOKUP
;
74 #define GB (1024UL * 1024UL * 1024UL)
77 cpci690_get_bus_freq(void)
79 if (boot_mem_size
>= (1*GB
)) /* bus speed based on mem size */
85 static const unsigned int cpu_750xx
[32] = { /* 750FX & 750GX */
86 0, 0, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,/* 0-15*/
87 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 0 /*16-31*/
91 cpci690_get_cpu_freq(void)
93 unsigned long pll_cfg
;
95 pll_cfg
= (mfspr(SPRN_HID1
) & 0xf8000000) >> 27;
96 return cpci690_get_bus_freq() * cpu_750xx
[pll_cfg
]/2;
100 cpci690_setup_bridge(void)
102 struct mv64x60_setup_info si
;
105 memset(&si
, 0, sizeof(si
));
107 si
.phys_reg_base
= CONFIG_MV64X60_NEW_BASE
;
109 si
.pci_0
.enable_bus
= 1;
110 si
.pci_0
.pci_io
.cpu_base
= CPCI690_PCI0_IO_START_PROC_ADDR
;
111 si
.pci_0
.pci_io
.pci_base_hi
= 0;
112 si
.pci_0
.pci_io
.pci_base_lo
= CPCI690_PCI0_IO_START_PCI_ADDR
;
113 si
.pci_0
.pci_io
.size
= CPCI690_PCI0_IO_SIZE
;
114 si
.pci_0
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
115 si
.pci_0
.pci_mem
[0].cpu_base
= CPCI690_PCI0_MEM_START_PROC_ADDR
;
116 si
.pci_0
.pci_mem
[0].pci_base_hi
= CPCI690_PCI0_MEM_START_PCI_HI_ADDR
;
117 si
.pci_0
.pci_mem
[0].pci_base_lo
= CPCI690_PCI0_MEM_START_PCI_LO_ADDR
;
118 si
.pci_0
.pci_mem
[0].size
= CPCI690_PCI0_MEM_SIZE
;
119 si
.pci_0
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
120 si
.pci_0
.pci_cmd_bits
= 0;
121 si
.pci_0
.latency_timer
= 0x80;
123 si
.pci_1
.enable_bus
= 1;
124 si
.pci_1
.pci_io
.cpu_base
= CPCI690_PCI1_IO_START_PROC_ADDR
;
125 si
.pci_1
.pci_io
.pci_base_hi
= 0;
126 si
.pci_1
.pci_io
.pci_base_lo
= CPCI690_PCI1_IO_START_PCI_ADDR
;
127 si
.pci_1
.pci_io
.size
= CPCI690_PCI1_IO_SIZE
;
128 si
.pci_1
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
129 si
.pci_1
.pci_mem
[0].cpu_base
= CPCI690_PCI1_MEM_START_PROC_ADDR
;
130 si
.pci_1
.pci_mem
[0].pci_base_hi
= CPCI690_PCI1_MEM_START_PCI_HI_ADDR
;
131 si
.pci_1
.pci_mem
[0].pci_base_lo
= CPCI690_PCI1_MEM_START_PCI_LO_ADDR
;
132 si
.pci_1
.pci_mem
[0].size
= CPCI690_PCI1_MEM_SIZE
;
133 si
.pci_1
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
134 si
.pci_1
.pci_cmd_bits
= 0;
135 si
.pci_1
.latency_timer
= 0x80;
137 for (i
=0; i
<MV64x60_CPU2MEM_WINDOWS
; i
++) {
138 si
.cpu_prot_options
[i
] = 0;
139 si
.cpu_snoop_options
[i
] = GT64260_CPU_SNOOP_WB
;
140 si
.pci_0
.acc_cntl_options
[i
] =
141 GT64260_PCI_ACC_CNTL_DREADEN
|
142 GT64260_PCI_ACC_CNTL_RDPREFETCH
|
143 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH
|
144 GT64260_PCI_ACC_CNTL_RDMULPREFETCH
|
145 GT64260_PCI_ACC_CNTL_SWAP_NONE
|
146 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES
;
147 si
.pci_0
.snoop_options
[i
] = GT64260_PCI_SNOOP_WB
;
148 si
.pci_1
.acc_cntl_options
[i
] =
149 GT64260_PCI_ACC_CNTL_DREADEN
|
150 GT64260_PCI_ACC_CNTL_RDPREFETCH
|
151 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH
|
152 GT64260_PCI_ACC_CNTL_RDMULPREFETCH
|
153 GT64260_PCI_ACC_CNTL_SWAP_NONE
|
154 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES
;
155 si
.pci_1
.snoop_options
[i
] = GT64260_PCI_SNOOP_WB
;
158 /* Lookup PCI host bridges */
159 if (mv64x60_init(&bh
, &si
))
160 printk(KERN_ERR
"Bridge initialization failed.\n");
162 pci_dram_offset
= 0; /* System mem at same addr on PCI & cpu bus */
163 ppc_md
.pci_swizzle
= common_swizzle
;
164 ppc_md
.pci_map_irq
= cpci690_map_irq
;
165 ppc_md
.pci_exclude_device
= mv64x60_pci_exclude_device
;
167 mv64x60_set_bus(&bh
, 0, 0);
168 bh
.hose_a
->first_busno
= 0;
169 bh
.hose_a
->last_busno
= 0xff;
170 bh
.hose_a
->last_busno
= pciauto_bus_scan(bh
.hose_a
, 0);
172 bh
.hose_b
->first_busno
= bh
.hose_a
->last_busno
+ 1;
173 mv64x60_set_bus(&bh
, 1, bh
.hose_b
->first_busno
);
174 bh
.hose_b
->last_busno
= 0xff;
175 bh
.hose_b
->last_busno
= pciauto_bus_scan(bh
.hose_b
,
176 bh
.hose_b
->first_busno
);
180 cpci690_setup_peripherals(void)
182 /* Set up windows to CPLD, RTC/TODC, IPMI. */
183 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_0_WIN
, CPCI690_BR_BASE
,
185 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_0_WIN
);
186 cpci690_br_base
= ioremap(CPCI690_BR_BASE
, CPCI690_BR_SIZE
);
188 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_1_WIN
, CPCI690_TODC_BASE
,
189 CPCI690_TODC_SIZE
, 0);
190 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_1_WIN
);
191 TODC_INIT(TODC_TYPE_MK48T35
, 0, 0,
192 ioremap(CPCI690_TODC_BASE
, CPCI690_TODC_SIZE
), 8);
194 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_2_WIN
, CPCI690_IPMI_BASE
,
195 CPCI690_IPMI_SIZE
, 0);
196 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_2_WIN
);
198 mv64x60_set_bits(&bh
, MV64x60_PCI0_ARBITER_CNTL
, (1<<31));
199 mv64x60_set_bits(&bh
, MV64x60_PCI1_ARBITER_CNTL
, (1<<31));
201 mv64x60_set_bits(&bh
, MV64x60_CPU_MASTER_CNTL
, (1<<9)); /* Only 1 cpu */
204 * Turn off timer/counters. Not turning off watchdog timer because
205 * can't read its reg on the 64260A so don't know if we'll be enabling
208 mv64x60_clr_bits(&bh
, MV64x60_TIMR_CNTR_0_3_CNTL
,
209 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
210 mv64x60_clr_bits(&bh
, GT64260_TIMR_CNTR_4_7_CNTL
,
211 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
214 * Set MPSC Multiplex RMII
215 * NOTE: ethernet driver modifies bit 0 and 1
217 mv64x60_write(&bh
, GT64260_MPP_SERIAL_PORTS_MULTIPLEX
, 0x00001102);
219 #define GPP_EXTERNAL_INTERRUPTS \
220 ((1<<24) | (1<<25) | (1<<26) | (1<<27) | \
221 (1<<28) | (1<<29) | (1<<30) | (1<<31))
222 /* PCI interrupts are inputs */
223 mv64x60_clr_bits(&bh
, MV64x60_GPP_IO_CNTL
, GPP_EXTERNAL_INTERRUPTS
);
224 /* PCI interrupts are active low */
225 mv64x60_set_bits(&bh
, MV64x60_GPP_LEVEL_CNTL
, GPP_EXTERNAL_INTERRUPTS
);
227 /* Clear any pending interrupts for these inputs and enable them. */
228 mv64x60_write(&bh
, MV64x60_GPP_INTR_CAUSE
, ~GPP_EXTERNAL_INTERRUPTS
);
229 mv64x60_set_bits(&bh
, MV64x60_GPP_INTR_MASK
, GPP_EXTERNAL_INTERRUPTS
);
231 /* Route MPP interrupt inputs to GPP */
232 mv64x60_write(&bh
, MV64x60_MPP_CNTL_2
, 0x00000000);
233 mv64x60_write(&bh
, MV64x60_MPP_CNTL_3
, 0x00000000);
237 cpci690_setup_arch(void)
240 ppc_md
.progress("cpci690_setup_arch: enter", 0);
241 #ifdef CONFIG_BLK_DEV_INITRD
243 ROOT_DEV
= Root_RAM0
;
246 #ifdef CONFIG_ROOT_NFS
249 ROOT_DEV
= Root_SDA2
;
253 ppc_md
.progress("cpci690_setup_arch: Enabling L2 cache", 0);
255 /* Enable L2 and L3 caches (if 745x) */
256 _set_L2CR(_get_L2CR() | L2CR_L2E
);
257 _set_L3CR(_get_L3CR() | L3CR_L3E
);
260 ppc_md
.progress("cpci690_setup_arch: Initializing bridge", 0);
262 cpci690_setup_bridge(); /* set up PCI bridge(s) */
263 cpci690_setup_peripherals(); /* set up chip selects/GPP/MPP etc */
266 ppc_md
.progress("cpci690_setup_arch: bridge init complete", 0);
268 printk(KERN_INFO
"%s %s port (C) 2003 MontaVista Software, Inc. "
269 "(source@mvista.com)\n", BOARD_VENDOR
, BOARD_MACHINE
);
272 ppc_md
.progress("cpci690_setup_arch: exit", 0);
275 /* Platform device data fixup routines. */
276 #if defined(CONFIG_SERIAL_MPSC)
278 cpci690_fixup_mpsc_pdata(struct platform_device
*pdev
)
280 struct mpsc_pdata
*pdata
;
282 pdata
= (struct mpsc_pdata
*)pdev
->dev
.platform_data
;
284 pdata
->max_idle
= 40;
285 pdata
->default_baud
= CPCI690_MPSC_BAUD
;
286 pdata
->brg_clk_src
= CPCI690_MPSC_CLK_SRC
;
287 pdata
->brg_clk_freq
= cpci690_get_bus_freq();
291 cpci690_platform_notify(struct device
*dev
)
295 void ((*rtn
)(struct platform_device
*pdev
));
297 { MPSC_CTLR_NAME
".0", cpci690_fixup_mpsc_pdata
},
298 { MPSC_CTLR_NAME
".1", cpci690_fixup_mpsc_pdata
},
300 struct platform_device
*pdev
;
303 if (dev
&& dev
->bus_id
)
304 for (i
=0; i
<ARRAY_SIZE(dev_map
); i
++)
305 if (!strncmp(dev
->bus_id
, dev_map
[i
].bus_id
,
308 pdev
= container_of(dev
,
309 struct platform_device
, dev
);
310 dev_map
[i
].rtn(pdev
);
318 cpci690_reset_board(void)
323 out_8((cpci690_br_base
+ CPCI690_BR_SW_RESET
), 0x11);
326 panic("restart failed\n");
330 cpci690_restart(char *cmd
)
332 cpci690_reset_board();
343 cpci690_power_off(void)
350 cpci690_show_cpuinfo(struct seq_file
*m
)
354 seq_printf(m
, "cpu MHz\t\t: %d\n",
355 (cpci690_get_cpu_freq() + 500000) / 1000000);
356 seq_printf(m
, "bus MHz\t\t: %d\n",
357 (cpci690_get_bus_freq() + 500000) / 1000000);
358 seq_printf(m
, "vendor\t\t: " BOARD_VENDOR
"\n");
359 seq_printf(m
, "machine\t\t: " BOARD_MACHINE
"\n");
360 seq_printf(m
, "FPGA Revision\t: %d\n",
361 in_8(cpci690_br_base
+ CPCI690_BR_MEM_CTLR
) >> 5);
364 case MV64x60_TYPE_GT64260A
:
367 case MV64x60_TYPE_GT64260B
:
370 case MV64x60_TYPE_MV64360
:
373 case MV64x60_TYPE_MV64460
:
379 seq_printf(m
, "bridge type\t: %s\n", s
);
380 seq_printf(m
, "bridge rev\t: 0x%x\n", bh
.rev
);
381 #if defined(CONFIG_NOT_COHERENT_CACHE)
382 seq_printf(m
, "coherency\t: %s\n", "off");
384 seq_printf(m
, "coherency\t: %s\n", "on");
391 cpci690_calibrate_decr(void)
395 freq
= cpci690_get_bus_freq() / 4;
397 printk(KERN_INFO
"time_init: decrementer frequency = %lu.%.6lu MHz\n",
398 freq
/1000000, freq
%1000000);
400 tb_ticks_per_jiffy
= freq
/ HZ
;
401 tb_to_us
= mulhwu_scale_factor(freq
, 1000000);
404 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC)
408 io_block_mapping(CONFIG_MV64X60_NEW_BASE
, CONFIG_MV64X60_NEW_BASE
,
409 128 * 1024, _PAGE_IO
);
414 platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
415 unsigned long r6
, unsigned long r7
)
417 parse_bootinfo(find_bootinfo());
419 #ifdef CONFIG_BLK_DEV_INITRD
420 /* take care of initrd if we have one */
422 initrd_start
= r4
+ KERNELBASE
;
423 initrd_end
= r5
+ KERNELBASE
;
425 #endif /* CONFIG_BLK_DEV_INITRD */
429 ppc_md
.setup_arch
= cpci690_setup_arch
;
430 ppc_md
.show_cpuinfo
= cpci690_show_cpuinfo
;
431 ppc_md
.init_IRQ
= gt64260_init_irq
;
432 ppc_md
.get_irq
= gt64260_get_irq
;
433 ppc_md
.restart
= cpci690_restart
;
434 ppc_md
.power_off
= cpci690_power_off
;
435 ppc_md
.halt
= cpci690_halt
;
436 ppc_md
.time_init
= todc_time_init
;
437 ppc_md
.set_rtc_time
= todc_set_rtc_time
;
438 ppc_md
.get_rtc_time
= todc_get_rtc_time
;
439 ppc_md
.nvram_read_val
= todc_direct_read_val
;
440 ppc_md
.nvram_write_val
= todc_direct_write_val
;
441 ppc_md
.calibrate_decr
= cpci690_calibrate_decr
;
443 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC)
444 ppc_md
.setup_io_mappings
= cpci690_map_io
;
445 #ifdef CONFIG_SERIAL_TEXT_DEBUG
446 ppc_md
.progress
= mv64x60_mpsc_progress
;
447 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE
);
448 #endif /* CONFIG_SERIAL_TEXT_DEBUG */
449 #endif /* defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC) */
451 #if defined(CONFIG_SERIAL_MPSC)
452 platform_notify
= cpci690_platform_notify
;