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/irq.h>
15 #include <linux/seq_file.h>
16 #include <linux/console.h>
17 #include <linux/initrd.h>
18 #include <linux/root_dev.h>
19 #include <linux/mv643xx.h>
20 #include <linux/platform_device.h>
21 #include <asm/bootinfo.h>
22 #include <asm/machdep.h>
25 #include <asm/mv64x60.h>
26 #include <platforms/cpci690.h>
28 #define BOARD_VENDOR "Force"
29 #define BOARD_MACHINE "CPCI690"
31 /* Set IDE controllers into Native mode? */
32 #define SET_PCI_IDE_NATIVE
34 static struct mv64x60_handle bh
;
35 static void __iomem
*cpci690_br_base
;
40 cpci690_map_irq(struct pci_dev
*dev
, unsigned char idsel
, unsigned char pin
)
42 struct pci_controller
*hose
= pci_bus_to_hose(dev
->bus
->number
);
44 if (hose
->index
== 0) {
45 static char pci_irq_table
[][4] =
47 * PCI IDSEL/INTPIN->INTLINE
51 { 90, 91, 88, 89 }, /* IDSEL 30/20 - Sentinel */
54 const long min_idsel
= 20, max_idsel
= 20, irqs_per_slot
= 4;
55 return PCI_IRQ_TABLE_LOOKUP
;
57 static char pci_irq_table
[][4] =
59 * PCI IDSEL/INTPIN->INTLINE
63 { 93, 94, 95, 92 }, /* IDSEL 28/18 - PMC slot 2 */
64 { 0, 0, 0, 0 }, /* IDSEL 29/19 - Not used */
65 { 94, 95, 92, 93 }, /* IDSEL 30/20 - PMC slot 1 */
68 const long min_idsel
= 18, max_idsel
= 20, irqs_per_slot
= 4;
69 return PCI_IRQ_TABLE_LOOKUP
;
73 #define GB (1024UL * 1024UL * 1024UL)
76 cpci690_get_bus_freq(void)
78 if (boot_mem_size
>= (1*GB
)) /* bus speed based on mem size */
84 static const unsigned int cpu_750xx
[32] = { /* 750FX & 750GX */
85 0, 0, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,/* 0-15*/
86 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 0 /*16-31*/
90 cpci690_get_cpu_freq(void)
92 unsigned long pll_cfg
;
94 pll_cfg
= (mfspr(SPRN_HID1
) & 0xf8000000) >> 27;
95 return cpci690_get_bus_freq() * cpu_750xx
[pll_cfg
]/2;
99 cpci690_setup_bridge(void)
101 struct mv64x60_setup_info si
;
104 memset(&si
, 0, sizeof(si
));
106 si
.phys_reg_base
= CONFIG_MV64X60_NEW_BASE
;
108 si
.pci_0
.enable_bus
= 1;
109 si
.pci_0
.pci_io
.cpu_base
= CPCI690_PCI0_IO_START_PROC_ADDR
;
110 si
.pci_0
.pci_io
.pci_base_hi
= 0;
111 si
.pci_0
.pci_io
.pci_base_lo
= CPCI690_PCI0_IO_START_PCI_ADDR
;
112 si
.pci_0
.pci_io
.size
= CPCI690_PCI0_IO_SIZE
;
113 si
.pci_0
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
114 si
.pci_0
.pci_mem
[0].cpu_base
= CPCI690_PCI0_MEM_START_PROC_ADDR
;
115 si
.pci_0
.pci_mem
[0].pci_base_hi
= CPCI690_PCI0_MEM_START_PCI_HI_ADDR
;
116 si
.pci_0
.pci_mem
[0].pci_base_lo
= CPCI690_PCI0_MEM_START_PCI_LO_ADDR
;
117 si
.pci_0
.pci_mem
[0].size
= CPCI690_PCI0_MEM_SIZE
;
118 si
.pci_0
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
119 si
.pci_0
.pci_cmd_bits
= 0;
120 si
.pci_0
.latency_timer
= 0x80;
122 si
.pci_1
.enable_bus
= 1;
123 si
.pci_1
.pci_io
.cpu_base
= CPCI690_PCI1_IO_START_PROC_ADDR
;
124 si
.pci_1
.pci_io
.pci_base_hi
= 0;
125 si
.pci_1
.pci_io
.pci_base_lo
= CPCI690_PCI1_IO_START_PCI_ADDR
;
126 si
.pci_1
.pci_io
.size
= CPCI690_PCI1_IO_SIZE
;
127 si
.pci_1
.pci_io
.swap
= MV64x60_CPU2PCI_SWAP_NONE
;
128 si
.pci_1
.pci_mem
[0].cpu_base
= CPCI690_PCI1_MEM_START_PROC_ADDR
;
129 si
.pci_1
.pci_mem
[0].pci_base_hi
= CPCI690_PCI1_MEM_START_PCI_HI_ADDR
;
130 si
.pci_1
.pci_mem
[0].pci_base_lo
= CPCI690_PCI1_MEM_START_PCI_LO_ADDR
;
131 si
.pci_1
.pci_mem
[0].size
= CPCI690_PCI1_MEM_SIZE
;
132 si
.pci_1
.pci_mem
[0].swap
= MV64x60_CPU2PCI_SWAP_NONE
;
133 si
.pci_1
.pci_cmd_bits
= 0;
134 si
.pci_1
.latency_timer
= 0x80;
136 for (i
=0; i
<MV64x60_CPU2MEM_WINDOWS
; i
++) {
137 si
.cpu_prot_options
[i
] = 0;
138 si
.cpu_snoop_options
[i
] = GT64260_CPU_SNOOP_WB
;
139 si
.pci_0
.acc_cntl_options
[i
] =
140 GT64260_PCI_ACC_CNTL_DREADEN
|
141 GT64260_PCI_ACC_CNTL_RDPREFETCH
|
142 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH
|
143 GT64260_PCI_ACC_CNTL_RDMULPREFETCH
|
144 GT64260_PCI_ACC_CNTL_SWAP_NONE
|
145 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES
;
146 si
.pci_0
.snoop_options
[i
] = GT64260_PCI_SNOOP_WB
;
147 si
.pci_1
.acc_cntl_options
[i
] =
148 GT64260_PCI_ACC_CNTL_DREADEN
|
149 GT64260_PCI_ACC_CNTL_RDPREFETCH
|
150 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH
|
151 GT64260_PCI_ACC_CNTL_RDMULPREFETCH
|
152 GT64260_PCI_ACC_CNTL_SWAP_NONE
|
153 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES
;
154 si
.pci_1
.snoop_options
[i
] = GT64260_PCI_SNOOP_WB
;
157 /* Lookup PCI host bridges */
158 if (mv64x60_init(&bh
, &si
))
159 printk(KERN_ERR
"Bridge initialization failed.\n");
161 pci_dram_offset
= 0; /* System mem at same addr on PCI & cpu bus */
162 ppc_md
.pci_swizzle
= common_swizzle
;
163 ppc_md
.pci_map_irq
= cpci690_map_irq
;
164 ppc_md
.pci_exclude_device
= mv64x60_pci_exclude_device
;
166 mv64x60_set_bus(&bh
, 0, 0);
167 bh
.hose_a
->first_busno
= 0;
168 bh
.hose_a
->last_busno
= 0xff;
169 bh
.hose_a
->last_busno
= pciauto_bus_scan(bh
.hose_a
, 0);
171 bh
.hose_b
->first_busno
= bh
.hose_a
->last_busno
+ 1;
172 mv64x60_set_bus(&bh
, 1, bh
.hose_b
->first_busno
);
173 bh
.hose_b
->last_busno
= 0xff;
174 bh
.hose_b
->last_busno
= pciauto_bus_scan(bh
.hose_b
,
175 bh
.hose_b
->first_busno
);
179 cpci690_setup_peripherals(void)
181 /* Set up windows to CPLD, RTC/TODC, IPMI. */
182 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_0_WIN
, CPCI690_BR_BASE
,
184 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_0_WIN
);
185 cpci690_br_base
= ioremap(CPCI690_BR_BASE
, CPCI690_BR_SIZE
);
187 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_1_WIN
, CPCI690_TODC_BASE
,
188 CPCI690_TODC_SIZE
, 0);
189 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_1_WIN
);
190 TODC_INIT(TODC_TYPE_MK48T35
, 0, 0,
191 ioremap(CPCI690_TODC_BASE
, CPCI690_TODC_SIZE
), 8);
193 mv64x60_set_32bit_window(&bh
, MV64x60_CPU2DEV_2_WIN
, CPCI690_IPMI_BASE
,
194 CPCI690_IPMI_SIZE
, 0);
195 bh
.ci
->enable_window_32bit(&bh
, MV64x60_CPU2DEV_2_WIN
);
197 mv64x60_set_bits(&bh
, MV64x60_PCI0_ARBITER_CNTL
, (1<<31));
198 mv64x60_set_bits(&bh
, MV64x60_PCI1_ARBITER_CNTL
, (1<<31));
200 mv64x60_set_bits(&bh
, MV64x60_CPU_MASTER_CNTL
, (1<<9)); /* Only 1 cpu */
203 * Turn off timer/counters. Not turning off watchdog timer because
204 * can't read its reg on the 64260A so don't know if we'll be enabling
207 mv64x60_clr_bits(&bh
, MV64x60_TIMR_CNTR_0_3_CNTL
,
208 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
209 mv64x60_clr_bits(&bh
, GT64260_TIMR_CNTR_4_7_CNTL
,
210 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
213 * Set MPSC Multiplex RMII
214 * NOTE: ethernet driver modifies bit 0 and 1
216 mv64x60_write(&bh
, GT64260_MPP_SERIAL_PORTS_MULTIPLEX
, 0x00001102);
218 #define GPP_EXTERNAL_INTERRUPTS \
219 ((1<<24) | (1<<25) | (1<<26) | (1<<27) | \
220 (1<<28) | (1<<29) | (1<<30) | (1<<31))
221 /* PCI interrupts are inputs */
222 mv64x60_clr_bits(&bh
, MV64x60_GPP_IO_CNTL
, GPP_EXTERNAL_INTERRUPTS
);
223 /* PCI interrupts are active low */
224 mv64x60_set_bits(&bh
, MV64x60_GPP_LEVEL_CNTL
, GPP_EXTERNAL_INTERRUPTS
);
226 /* Clear any pending interrupts for these inputs and enable them. */
227 mv64x60_write(&bh
, MV64x60_GPP_INTR_CAUSE
, ~GPP_EXTERNAL_INTERRUPTS
);
228 mv64x60_set_bits(&bh
, MV64x60_GPP_INTR_MASK
, GPP_EXTERNAL_INTERRUPTS
);
230 /* Route MPP interrupt inputs to GPP */
231 mv64x60_write(&bh
, MV64x60_MPP_CNTL_2
, 0x00000000);
232 mv64x60_write(&bh
, MV64x60_MPP_CNTL_3
, 0x00000000);
236 cpci690_setup_arch(void)
239 ppc_md
.progress("cpci690_setup_arch: enter", 0);
240 #ifdef CONFIG_BLK_DEV_INITRD
242 ROOT_DEV
= Root_RAM0
;
245 #ifdef CONFIG_ROOT_NFS
248 ROOT_DEV
= Root_SDA2
;
252 ppc_md
.progress("cpci690_setup_arch: Enabling L2 cache", 0);
254 /* Enable L2 and L3 caches (if 745x) */
255 _set_L2CR(_get_L2CR() | L2CR_L2E
);
256 _set_L3CR(_get_L3CR() | L3CR_L3E
);
259 ppc_md
.progress("cpci690_setup_arch: Initializing bridge", 0);
261 cpci690_setup_bridge(); /* set up PCI bridge(s) */
262 cpci690_setup_peripherals(); /* set up chip selects/GPP/MPP etc */
265 ppc_md
.progress("cpci690_setup_arch: bridge init complete", 0);
267 printk(KERN_INFO
"%s %s port (C) 2003 MontaVista Software, Inc. "
268 "(source@mvista.com)\n", BOARD_VENDOR
, BOARD_MACHINE
);
271 ppc_md
.progress("cpci690_setup_arch: exit", 0);
274 /* Platform device data fixup routines. */
275 #if defined(CONFIG_SERIAL_MPSC)
277 cpci690_fixup_mpsc_pdata(struct platform_device
*pdev
)
279 struct mpsc_pdata
*pdata
;
281 pdata
= (struct mpsc_pdata
*)pdev
->dev
.platform_data
;
283 pdata
->max_idle
= 40;
284 pdata
->default_baud
= CPCI690_MPSC_BAUD
;
285 pdata
->brg_clk_src
= CPCI690_MPSC_CLK_SRC
;
286 pdata
->brg_clk_freq
= cpci690_get_bus_freq();
290 cpci690_platform_notify(struct device
*dev
)
294 void ((*rtn
)(struct platform_device
*pdev
));
296 { MPSC_CTLR_NAME
".0", cpci690_fixup_mpsc_pdata
},
297 { MPSC_CTLR_NAME
".1", cpci690_fixup_mpsc_pdata
},
299 struct platform_device
*pdev
;
302 if (dev
&& dev
->bus_id
)
303 for (i
=0; i
<ARRAY_SIZE(dev_map
); i
++)
304 if (!strncmp(dev
->bus_id
, dev_map
[i
].bus_id
,
307 pdev
= container_of(dev
,
308 struct platform_device
, dev
);
309 dev_map
[i
].rtn(pdev
);
317 cpci690_reset_board(void)
322 out_8((cpci690_br_base
+ CPCI690_BR_SW_RESET
), 0x11);
325 panic("restart failed\n");
329 cpci690_restart(char *cmd
)
331 cpci690_reset_board();
342 cpci690_power_off(void)
349 cpci690_show_cpuinfo(struct seq_file
*m
)
353 seq_printf(m
, "cpu MHz\t\t: %d\n",
354 (cpci690_get_cpu_freq() + 500000) / 1000000);
355 seq_printf(m
, "bus MHz\t\t: %d\n",
356 (cpci690_get_bus_freq() + 500000) / 1000000);
357 seq_printf(m
, "vendor\t\t: " BOARD_VENDOR
"\n");
358 seq_printf(m
, "machine\t\t: " BOARD_MACHINE
"\n");
359 seq_printf(m
, "FPGA Revision\t: %d\n",
360 in_8(cpci690_br_base
+ CPCI690_BR_MEM_CTLR
) >> 5);
363 case MV64x60_TYPE_GT64260A
:
366 case MV64x60_TYPE_GT64260B
:
369 case MV64x60_TYPE_MV64360
:
372 case MV64x60_TYPE_MV64460
:
378 seq_printf(m
, "bridge type\t: %s\n", s
);
379 seq_printf(m
, "bridge rev\t: 0x%x\n", bh
.rev
);
380 #if defined(CONFIG_NOT_COHERENT_CACHE)
381 seq_printf(m
, "coherency\t: %s\n", "off");
383 seq_printf(m
, "coherency\t: %s\n", "on");
390 cpci690_calibrate_decr(void)
394 freq
= cpci690_get_bus_freq() / 4;
396 printk(KERN_INFO
"time_init: decrementer frequency = %lu.%.6lu MHz\n",
397 freq
/1000000, freq
%1000000);
399 tb_ticks_per_jiffy
= freq
/ HZ
;
400 tb_to_us
= mulhwu_scale_factor(freq
, 1000000);
403 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC)
407 io_block_mapping(CONFIG_MV64X60_NEW_BASE
, CONFIG_MV64X60_NEW_BASE
,
408 128 * 1024, _PAGE_IO
);
413 platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
414 unsigned long r6
, unsigned long r7
)
416 parse_bootinfo(find_bootinfo());
418 #ifdef CONFIG_BLK_DEV_INITRD
419 /* take care of initrd if we have one */
421 initrd_start
= r4
+ KERNELBASE
;
422 initrd_end
= r5
+ KERNELBASE
;
424 #endif /* CONFIG_BLK_DEV_INITRD */
428 ppc_md
.setup_arch
= cpci690_setup_arch
;
429 ppc_md
.show_cpuinfo
= cpci690_show_cpuinfo
;
430 ppc_md
.init_IRQ
= gt64260_init_irq
;
431 ppc_md
.get_irq
= gt64260_get_irq
;
432 ppc_md
.restart
= cpci690_restart
;
433 ppc_md
.power_off
= cpci690_power_off
;
434 ppc_md
.halt
= cpci690_halt
;
435 ppc_md
.time_init
= todc_time_init
;
436 ppc_md
.set_rtc_time
= todc_set_rtc_time
;
437 ppc_md
.get_rtc_time
= todc_get_rtc_time
;
438 ppc_md
.nvram_read_val
= todc_direct_read_val
;
439 ppc_md
.nvram_write_val
= todc_direct_write_val
;
440 ppc_md
.calibrate_decr
= cpci690_calibrate_decr
;
442 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC)
443 ppc_md
.setup_io_mappings
= cpci690_map_io
;
444 #ifdef CONFIG_SERIAL_TEXT_DEBUG
445 ppc_md
.progress
= mv64x60_mpsc_progress
;
446 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE
);
447 #endif /* CONFIG_SERIAL_TEXT_DEBUG */
448 #endif /* defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC) */
450 #if defined(CONFIG_SERIAL_MPSC)
451 platform_notify
= cpci690_platform_notify
;