Commit | Line | Data |
---|---|---|
89d63fe1 | 1 | /* |
89d63fe1 AN |
2 | * Based on linux/arch/mips/txx9/rbtx4938/setup.c, |
3 | * and RBTX49xx patch from CELF patch archive. | |
4 | * | |
5 | * Copyright 2001, 2003-2005 MontaVista Software Inc. | |
6 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) | |
7 | * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 | |
8 | * | |
9 | * This file is subject to the terms and conditions of the GNU General Public | |
10 | * License. See the file "COPYING" in the main directory of this archive | |
11 | * for more details. | |
12 | */ | |
13 | #include <linux/init.h> | |
14 | #include <linux/pci.h> | |
15 | #include <linux/kernel.h> | |
455cc256 | 16 | #include <linux/interrupt.h> |
89d63fe1 AN |
17 | #include <asm/txx9/generic.h> |
18 | #include <asm/txx9/tx4938.h> | |
19 | ||
20 | int __init tx4938_report_pciclk(void) | |
21 | { | |
22 | int pciclk = 0; | |
23 | ||
24 | printk(KERN_INFO "PCIC --%s PCICLK:", | |
25 | (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ? | |
26 | " PCI66" : ""); | |
27 | if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { | |
28 | u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); | |
29 | switch ((unsigned long)ccfg & | |
30 | TX4938_CCFG_PCIDIVMODE_MASK) { | |
31 | case TX4938_CCFG_PCIDIVMODE_4: | |
32 | pciclk = txx9_cpu_clock / 4; break; | |
33 | case TX4938_CCFG_PCIDIVMODE_4_5: | |
34 | pciclk = txx9_cpu_clock * 2 / 9; break; | |
35 | case TX4938_CCFG_PCIDIVMODE_5: | |
36 | pciclk = txx9_cpu_clock / 5; break; | |
37 | case TX4938_CCFG_PCIDIVMODE_5_5: | |
38 | pciclk = txx9_cpu_clock * 2 / 11; break; | |
39 | case TX4938_CCFG_PCIDIVMODE_8: | |
40 | pciclk = txx9_cpu_clock / 8; break; | |
41 | case TX4938_CCFG_PCIDIVMODE_9: | |
42 | pciclk = txx9_cpu_clock / 9; break; | |
43 | case TX4938_CCFG_PCIDIVMODE_10: | |
44 | pciclk = txx9_cpu_clock / 10; break; | |
45 | case TX4938_CCFG_PCIDIVMODE_11: | |
46 | pciclk = txx9_cpu_clock / 11; break; | |
47 | } | |
48 | printk("Internal(%u.%uMHz)", | |
49 | (pciclk + 50000) / 1000000, | |
50 | ((pciclk + 50000) / 100000) % 10); | |
51 | } else { | |
52 | printk("External"); | |
53 | pciclk = -1; | |
54 | } | |
55 | printk("\n"); | |
56 | return pciclk; | |
57 | } | |
58 | ||
59 | void __init tx4938_report_pci1clk(void) | |
60 | { | |
61 | __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); | |
62 | unsigned int pciclk = | |
63 | txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2); | |
64 | ||
65 | printk(KERN_INFO "PCIC1 -- %sPCICLK:%u.%uMHz\n", | |
66 | (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "", | |
67 | (pciclk + 50000) / 1000000, | |
68 | ((pciclk + 50000) / 100000) % 10); | |
69 | } | |
70 | ||
71 | int __init tx4938_pciclk66_setup(void) | |
72 | { | |
73 | int pciclk; | |
74 | ||
75 | /* Assert M66EN */ | |
76 | tx4938_ccfg_set(TX4938_CCFG_PCI66); | |
77 | /* Double PCICLK (if possible) */ | |
78 | if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { | |
79 | unsigned int pcidivmode = 0; | |
80 | u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); | |
81 | pcidivmode = (unsigned long)ccfg & | |
82 | TX4938_CCFG_PCIDIVMODE_MASK; | |
83 | switch (pcidivmode) { | |
84 | case TX4938_CCFG_PCIDIVMODE_8: | |
85 | case TX4938_CCFG_PCIDIVMODE_4: | |
86 | pcidivmode = TX4938_CCFG_PCIDIVMODE_4; | |
87 | pciclk = txx9_cpu_clock / 4; | |
88 | break; | |
89 | case TX4938_CCFG_PCIDIVMODE_9: | |
90 | case TX4938_CCFG_PCIDIVMODE_4_5: | |
91 | pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; | |
92 | pciclk = txx9_cpu_clock * 2 / 9; | |
93 | break; | |
94 | case TX4938_CCFG_PCIDIVMODE_10: | |
95 | case TX4938_CCFG_PCIDIVMODE_5: | |
96 | pcidivmode = TX4938_CCFG_PCIDIVMODE_5; | |
97 | pciclk = txx9_cpu_clock / 5; | |
98 | break; | |
99 | case TX4938_CCFG_PCIDIVMODE_11: | |
100 | case TX4938_CCFG_PCIDIVMODE_5_5: | |
101 | default: | |
102 | pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; | |
103 | pciclk = txx9_cpu_clock * 2 / 11; | |
104 | break; | |
105 | } | |
106 | tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK, | |
107 | pcidivmode); | |
108 | printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", | |
109 | (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg)); | |
110 | } else | |
111 | pciclk = -1; | |
112 | return pciclk; | |
113 | } | |
114 | ||
ee25d33f | 115 | int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) |
89d63fe1 AN |
116 | { |
117 | if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { | |
118 | switch (slot) { | |
119 | case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): | |
120 | if (__raw_readq(&tx4938_ccfgptr->pcfg) & | |
121 | TX4938_PCFG_ETH0_SEL) | |
122 | return TXX9_IRQ_BASE + TX4938_IR_ETH0; | |
123 | break; | |
124 | case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): | |
125 | if (__raw_readq(&tx4938_ccfgptr->pcfg) & | |
126 | TX4938_PCFG_ETH1_SEL) | |
127 | return TXX9_IRQ_BASE + TX4938_IR_ETH1; | |
128 | break; | |
129 | } | |
130 | return 0; | |
131 | } | |
132 | return -1; | |
133 | } | |
455cc256 AN |
134 | |
135 | void __init tx4938_setup_pcierr_irq(void) | |
136 | { | |
137 | if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR, | |
138 | tx4927_pcierr_interrupt, | |
139 | IRQF_DISABLED, "PCI error", | |
140 | (void *)TX4927_PCIC_REG)) | |
141 | printk(KERN_WARNING "Failed to request irq for PCIERR\n"); | |
142 | } |