Merge with /home/sr/git/u-boot/4xx-sdram
[platform/kernel/u-boot.git] / board / mvblue / mvblue.c
1 /*
2  * GNU General Public License for more details.
3  *
4  * MATRIX Vision GmbH / June 2002-Nov 2003
5  * Andre Schwarz
6  */
7
8 #include <common.h>
9 #include <mpc824x.h>
10 #include <asm/io.h>
11 #include <ns16550.h>
12
13 #ifdef CONFIG_PCI
14 #include <pci.h>
15 #endif
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 u32 get_BoardType (void);
20
21 #define PCI_CONFIG(b,d,f,r)    cpu_to_le32(0x80000000 | ((b&0xff)<<16) \
22                                                       | ((d&0x1f)<<11) \
23                                                       | ((f&0x7)<<7)   \
24                                                       | (r&0xfc) )
25
26 int mv_pci_read (int bus, int dev, int func, int reg)
27 {
28         *(u32 *) (0xfec00cf8) = PCI_CONFIG (bus, dev, func, reg);
29         asm ("sync");
30         return cpu_to_le32 (*(u32 *) (0xfee00cfc));
31 }
32
33 u32 get_BoardType ()
34 {
35         return (mv_pci_read (0, 0xe, 0, 0) == 0x06801095 ? 0 : 1);
36 }
37
38 void init_2nd_DUART (void)
39 {
40         NS16550_t console = (NS16550_t) CFG_NS16550_COM2;
41         int clock_divisor = CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE;
42
43         *(u8 *) (0xfc004511) = 0x1;
44         NS16550_init (console, clock_divisor);
45 }
46 void hw_watchdog_reset (void)
47 {
48         if (get_BoardType () == 0) {
49                 *(u32 *) (0xff000005) = 0;
50                 asm ("sync");
51         }
52 }
53 int checkboard (void)
54 {
55         ulong busfreq = get_bus_freq (0);
56         char buf[32];
57         u32 BoardType = get_BoardType ();
58         char *BoardName[2] = { "mvBlueBOX", "mvBlueLYNX" };
59         char *p;
60         bd_t *bd = gd->bd;
61
62         hw_watchdog_reset ();
63
64         printf ("U-Boot (%s) running on mvBLUE device.\n", MV_VERSION);
65         printf ("       Found %s running at %s MHz memory clock.\n",
66                 BoardName[BoardType], strmhz (buf, busfreq));
67
68         init_2nd_DUART ();
69
70         if ((p = getenv ("console_nr")) != NULL) {
71                 unsigned long con_nr = simple_strtoul (p, NULL, 10) & 3;
72
73                 bd->bi_baudrate &= ~3;
74                 bd->bi_baudrate |= con_nr & 3;
75         }
76         return 0;
77 }
78
79 long int initdram (int board_type)
80 {
81         long size;
82         long new_bank0_end;
83         long mear1;
84         long emear1;
85
86         size = get_ram_size(CFG_SDRAM_BASE, CFG_MAX_RAM_SIZE);
87
88         new_bank0_end = size - 1;
89         mear1 = mpc824x_mpc107_getreg(MEAR1);
90         emear1 = mpc824x_mpc107_getreg(EMEAR1);
91         mear1 = (mear1  & 0xFFFFFF00) |
92                 ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
93         emear1 = (emear1 & 0xFFFFFF00) |
94                 ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
95         mpc824x_mpc107_setreg(MEAR1,  mear1);
96         mpc824x_mpc107_setreg(EMEAR1, emear1);
97
98         return (size);
99 }
100
101 /* ------------------------------------------------------------------------- */
102 u8 *dhcp_vendorex_prep (u8 * e)
103 {
104         char *ptr;
105
106         /* DHCP vendor-class-identifier = 60 */
107         if ((ptr = getenv ("dhcp_vendor-class-identifier"))) {
108                 *e++ = 60;
109                 *e++ = strlen (ptr);
110                 while (*ptr)
111                         *e++ = *ptr++;
112         }
113         /* my DHCP_CLIENT_IDENTIFIER = 61 */
114         if ((ptr = getenv ("dhcp_client_id"))) {
115                 *e++ = 61;
116                 *e++ = strlen (ptr);
117                 while (*ptr)
118                         *e++ = *ptr++;
119         }
120         return e;
121 }
122
123 u8 *dhcp_vendorex_proc (u8 * popt)
124 {
125         return NULL;
126 }
127
128 /* ------------------------------------------------------------------------- */
129
130 /*
131  * Initialize PCI Devices
132  */
133 #ifdef CONFIG_PCI
134 void pci_mvblue_clear_base (struct pci_controller *hose, pci_dev_t dev)
135 {
136         u32 cnt;
137
138         printf ("clear base @ dev/func 0x%02x/0x%02x ... ", PCI_DEV (dev),
139                 PCI_FUNC (dev));
140         for (cnt = 0; cnt < 6; cnt++)
141                 pci_hose_write_config_dword (hose, dev, 0x10 + (4 * cnt),
142                                              0x0);
143         printf ("done\n");
144 }
145
146 void duart_setup (u32 base, u16 divisor)
147 {
148         printf ("duart setup ...");
149         out_8 ((u8 *) (CFG_ISA_IO + base + 3), 0x80);
150         out_8 ((u8 *) (CFG_ISA_IO + base + 0), divisor & 0xff);
151         out_8 ((u8 *) (CFG_ISA_IO + base + 1), divisor >> 8);
152         out_8 ((u8 *) (CFG_ISA_IO + base + 3), 0x03);
153         out_8 ((u8 *) (CFG_ISA_IO + base + 4), 0x03);
154         out_8 ((u8 *) (CFG_ISA_IO + base + 2), 0x07);
155         printf ("done\n");
156 }
157
158 void pci_mvblue_fixup_irq_behind_bridge (struct pci_controller *hose,
159                                          pci_dev_t bridge, unsigned char irq)
160 {
161         pci_dev_t d;
162         unsigned char bus;
163         unsigned short vendor, class;
164
165         pci_hose_read_config_byte (hose, bridge, PCI_SECONDARY_BUS, &bus);
166         for (d = PCI_BDF (bus, 0, 0);
167              d < PCI_BDF (bus, PCI_MAX_PCI_DEVICES - 1,
168                           PCI_MAX_PCI_FUNCTIONS - 1);
169              d += PCI_BDF (0, 0, 1)) {
170                 pci_hose_read_config_word (hose, d, PCI_VENDOR_ID, &vendor);
171                 if (vendor != 0xffff && vendor != 0x0000) {
172                         pci_hose_read_config_word (hose, d, PCI_CLASS_DEVICE,
173                                                    &class);
174                         if (class == PCI_CLASS_BRIDGE_PCI)
175                                 pci_mvblue_fixup_irq_behind_bridge (hose, d,
176                                                                     irq);
177                         else
178                                 pci_hose_write_config_byte (hose, d,
179                                                             PCI_INTERRUPT_LINE,
180                                                             irq);
181                 }
182         }
183 }
184
185 #define MV_MAX_PCI_BUSSES       3
186 #define SLOT0_IRQ       3
187 #define SLOT1_IRQ       4
188 void pci_mvblue_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
189 {
190         unsigned char line = 0xff;
191         unsigned short class;
192
193         if (PCI_BUS (dev) == 0) {
194                 switch (PCI_DEV (dev)) {
195                 case 0xd:
196                         if (get_BoardType () == 0) {
197                                 line = 1;
198                         } else
199                                 /* mvBL */
200                                 line = 2;
201                         break;
202                 case 0xe:
203                         /* mvBB: IDE */
204                         line = 2;
205                         pci_hose_write_config_byte (hose, dev, 0x8a, 0x20);
206                         break;
207                 case 0xf:
208                         /* mvBB: Slot0 (Grabber) */
209                         pci_hose_read_config_word (hose, dev,
210                                                    PCI_CLASS_DEVICE, &class);
211                         if (class == PCI_CLASS_BRIDGE_PCI) {
212                                 pci_mvblue_fixup_irq_behind_bridge (hose, dev,
213                                                                     SLOT0_IRQ);
214                                 line = 0xff;
215                         } else
216                                 line = SLOT0_IRQ;
217                         break;
218                 case 0x10:
219                         /* mvBB: Slot1 */
220                         pci_hose_read_config_word (hose, dev,
221                                                    PCI_CLASS_DEVICE, &class);
222                         if (class == PCI_CLASS_BRIDGE_PCI) {
223                                 pci_mvblue_fixup_irq_behind_bridge (hose, dev,
224                                                                     SLOT1_IRQ);
225                                 line = 0xff;
226                         } else
227                                 line = SLOT1_IRQ;
228                         break;
229                 default:
230                         printf ("***pci_scan: illegal dev = 0x%08x\n",
231                                 PCI_DEV (dev));
232                         line = 0xff;
233                         break;
234                 }
235                 pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE,
236                                             line);
237         }
238 }
239
240 struct pci_controller hose = {
241         fixup_irq:pci_mvblue_fixup_irq
242 };
243
244 void pci_init_board (void)
245 {
246         pci_mpc824x_init (&hose);
247 }
248 #endif