1 /*********************************************************************
3 * Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
17 * THIS SOFTWARE IS PROVIDED BY Raza Microelectronics, Inc. ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGE.
29 * *****************************RMI_2**********************************/
30 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
31 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/systm.h>
35 #include <sys/kernel.h>
37 #include <sys/mutex.h>
39 #include <machine/cpufunc.h>
40 #include <mips/rmi/msgring.h>
41 #include <mips/rmi/rmi_boot_info.h>
42 #include <mips/rmi/board.h>
43 #include <mips/rmi/pic.h>
45 #define XLR_I2C_RTC_ADDR 0xd0
46 #define XLR_I2C_EEPROM_ADDR 0xa0
47 #define XLR_I2C_TEMPSENSOR_ADDR 0x98
48 #define XLR_I2C_ATX8_TEMPSENSOR_ADDR 0x9a
50 struct stn_cc *xlr_core_cc_configs[] = { &cc_table_cpu_0, &cc_table_cpu_1,
51 &cc_table_cpu_2, &cc_table_cpu_3, &cc_table_cpu_4, &cc_table_cpu_5,
52 &cc_table_cpu_6, &cc_table_cpu_7};
54 struct stn_cc *xls_core_cc_configs[] = { &xls_cc_table_cpu_0, &xls_cc_table_cpu_1,
55 &xls_cc_table_cpu_2, &xls_cc_table_cpu_3 };
57 struct xlr_board_info xlr_board_info;
60 xlr_pcmcia_present(void)
62 xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_GPIO_OFFSET);
65 resetconf = xlr_read_reg(mmio, 21);
66 return ((resetconf & 0x4000) != 0);
70 xlr_chip_specific_overrides(struct xlr_board_info* board)
72 struct xlr_gmac_block_t *blk0, *blk1, *blk2;
76 blk0 = &board->gmac_block[0];
77 blk1 = &board->gmac_block[1];
78 blk2 = &board->gmac_block[2];
80 chipid = xlr_processor_id();
81 revision = xlr_revision();
83 if (revision == 0x04) { /* B2 */
85 case 0x07: /* XLR 508 */
86 case 0x08: /* XLR 516 */
87 case 0x09: /* XLR 532 */
88 /* NA[12] not available */
89 memset(blk1, 0, sizeof(*blk1));
90 memset(blk2, 0, sizeof(*blk2));
92 case 0x06: /* XLR 308 */
94 blk0->gmac_port[3].valid = 0;
96 /* NA[12] not available */
97 memset(blk1, 0, sizeof(*blk1));
98 memset(blk2, 0, sizeof(*blk2));
103 } else if (revision == 0x91) { /* C4 */
105 case 0x0B: /* XLR 508 */
106 case 0x0A: /* XLR 516 */
107 case 0x08: /* XLR 532 */
108 /* NA[12] not available */
109 memset(blk1, 0, sizeof(*blk1));
110 memset(blk2, 0, sizeof(*blk2));
112 case 0x0F: /* XLR 308 */
113 /* NA0 has 3 ports */
114 blk0->gmac_port[3].valid = 0;
116 /* NA[12] not available */
117 memset(blk1, 0, sizeof(*blk1));
118 memset(blk2, 0, sizeof(*blk2));
123 } else { /* other pre-production silicon */
131 /* NA[12] not available */
132 memset(blk1, 0, sizeof(*blk1));
133 memset(blk2, 0, sizeof(*blk2));
138 /* NA0 has 3 ports */
139 blk0->gmac_port[3].valid = 0;
141 /* NA[12] not available */
142 memset(blk1, 0, sizeof(*blk1));
143 memset(blk2, 0, sizeof(*blk2));
152 xlr_board_specific_overrides(struct xlr_board_info* board)
154 struct xlr_gmac_block_t *blk1, *blk2;
156 blk1 = &board->gmac_block[1];
157 blk2 = &board->gmac_block[2];
159 switch (xlr_boot1_info.board_major_version) {
160 case RMI_XLR_BOARD_ARIZONA_I:
161 /* ATX-I has SPI-4, not XGMAC */
162 blk1->type = XLR_SPI4;
163 blk1->enabled = 0; /* nlge does not
165 blk2->type = XLR_SPI4;
169 case RMI_XLR_BOARD_ARIZONA_II:
170 /* XGMII_A --> VSC7281, XGMII_B --> VSC7281 */
173 blk1->gmac_port[0].valid = 1;
177 blk2->gmac_port[0].valid = 1;
186 xlr_reg_t *gpio_mmio =
187 (unsigned int *)(DEFAULT_XLR_IO_BASE + XLR_IO_GPIO_OFFSET);
190 bit24 = (xlr_read_reg(gpio_mmio, 0x15) >> 24) & 0x1;
197 xlr_reg_t *gpio_mmio =
198 (unsigned int *)(DEFAULT_XLR_IO_BASE + XLR_IO_GPIO_OFFSET);
201 bit25 = (xlr_read_reg(gpio_mmio, 0x15) >> 25) & 0x1;
206 xls_chip_specific_overrides(struct xlr_board_info* board)
208 struct xlr_gmac_block_t *blk0, *blk1;
211 blk0 = &board->gmac_block[0];
212 blk1 = &board->gmac_block[1];
213 chipid = xlr_processor_id();
216 case 0x8E: /* XLS208 */
217 case 0x8F: /* XLS204 */
218 /* NA1 is not available */
219 memset(blk1, 0, sizeof(*blk1));
221 case 0xCE: /* XLS108 */
222 case 0xCF: /* XLS104 */
223 /* NA0 has 3 ports */
224 blk0->gmac_port[3].valid = 0;
226 /* NA1 is not available */
227 memset(blk1, 0, sizeof(*blk1));
235 xls_board_specific_overrides(struct xlr_board_info* board)
237 struct xlr_gmac_block_t *blk0, *blk1;
239 struct xlr_i2c_dev_t* iic_blk;
241 blk0 = &board->gmac_block[0];
242 blk1 = &board->gmac_block[1];
244 switch (xlr_boot1_info.board_major_version) {
245 case RMI_XLR_BOARD_ARIZONA_VI:
246 blk0->mode = XLR_PORT0_RGMII;
247 blk0->gmac_port[0].type = XLR_RGMII;
248 blk0->gmac_port[0].phy_addr = 0;
249 blk0->gmac_port[0].mii_addr = XLR_IO_GMAC_4_OFFSET;
250 /* Because of the Octal PHY, SGMII Quad1 is MII is also bound
251 * to the PHY attached to SGMII0_MDC/MDIO/MDINT. */
252 for (i = 0; i < 4; i++) {
253 blk1->gmac_port[i].mii_addr = XLR_IO_GMAC_0_OFFSET;
254 blk1->gmac_port[i].serdes_addr = XLR_IO_GMAC_0_OFFSET;
256 blk1->gmac_port[1].mii_addr = XLR_IO_GMAC_0_OFFSET;
257 blk1->gmac_port[2].mii_addr = XLR_IO_GMAC_0_OFFSET;
258 blk1->gmac_port[3].mii_addr = XLR_IO_GMAC_0_OFFSET;
260 blk1->gmac_port[1].serdes_addr = XLR_IO_GMAC_0_OFFSET;
261 blk1->gmac_port[2].serdes_addr = XLR_IO_GMAC_0_OFFSET;
262 blk1->gmac_port[3].serdes_addr = XLR_IO_GMAC_0_OFFSET;
264 /* RGMII MDIO interrupt is thru NA1 and SGMII MDIO
265 * interrupts for ports in blk1 are from NA0 */
266 blk0->gmac_port[0].mdint_id = 1;
268 blk1->gmac_port[0].mdint_id = 0;
269 blk1->gmac_port[1].mdint_id = 0;
270 blk1->gmac_port[2].mdint_id = 0;
271 blk1->gmac_port[3].mdint_id = 0;
273 /* If we have a 4xx lite chip, don't enable the
274 * GMACs which are disabled in hardware */
275 if (xlr_is_xls4xx_lite()) {
276 xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_GPIO_OFFSET);
279 /* Port 6 & 7 are not enabled on the condor 4xx, figure
280 * this out from the GPIO fuse bank */
281 tmp = xlr_read_reg(mmio, 35);
282 if ((tmp & (3 << 28)) != 0) {
284 blk1->gmac_port[2].valid = 0;
285 blk1->gmac_port[3].valid = 0;
291 case RMI_XLR_BOARD_ARIZONA_VIII:
292 iic_blk = &xlr_board_info.xlr_i2c_device[I2C_THERMAL];
293 if (iic_blk->enabled) {
294 iic_blk->addr = XLR_I2C_ATX8_TEMPSENSOR_ADDR;
297 /* There is just one Octal PHY on the board and it is
298 * connected to the MII interface for NA Quad 0. */
299 for (i = 0; i < 4; i++) {
300 blk1->gmac_port[i].mii_addr =
301 XLR_IO_GMAC_0_OFFSET;
302 blk1->gmac_port[i].mdint_id = 0;
307 case RMI_XLR_BOARD_ARIZONA_XI:
308 case RMI_XLR_BOARD_ARIZONA_XII:
309 if (quad0_xaui()) { /* GMAC ports 0-3 are set to XAUI */
310 /* only GMAC0 is active i.e, the 0-th port on this quad.
311 * Disable all the other 7 possible ports. */
312 for (i = 1; i < MAX_NA_PORTS; i++) {
313 memset(&blk0->gmac_port[i], 0,
314 sizeof(blk0->gmac_port[i]));
316 /* Setup for XAUI on N/w Acc0: gmac0 */
317 blk0->type = XLR_XGMAC;
318 blk0->mode = XLR_XAUI;
320 blk0->gmac_port[0].type = XLR_XAUI;
321 blk1->gmac_port[0].phy_addr = 16;
322 blk0->gmac_port[0].tx_bucket_id = blk0->station_txbase;
323 /* Other addresses etc need not be modified as XAUI_0
324 * shares its addresses with SGMII GMAC_0, which was
325 * set in the caller. */
328 blk0->num_ports = 1; /* only 1 RGMII port */
329 blk0->mode = XLR_PORT0_RGMII;
330 blk0->gmac_port[0].type = XLR_RGMII;
331 blk0->gmac_port[0].phy_addr = 0;
332 blk0->gmac_port[0].mii_addr = XLR_IO_GMAC_0_OFFSET;
335 if (quad1_xaui()) { /* GMAC ports 4-7 are used for XAUI */
336 /* only GMAC4 is active i.e, the 0-th port on this quad.
337 * Disable all the other 7 possible ports. */
338 for (i = 1; i < MAX_NA_PORTS; i++) {
339 memset(&blk1->gmac_port[i], 0,
340 sizeof(blk1->gmac_port[i]));
342 /* Setup for XAUI on N/w Acc1: gmac4 */
343 blk1->type = XLR_XGMAC;
344 blk1->mode = XLR_XAUI;
346 /* XAUI and SGMII ports share FMN buckets on N/w Acc 1;
347 so, station_txbase, station_rfr need not be
349 blk1->gmac_port[0].type = XLR_XAUI;
350 blk1->gmac_port[0].phy_addr = 16;
351 blk1->gmac_port[0].tx_bucket_id = blk1->station_txbase;
352 /* Other addresses etc need not be modified as XAUI_1
353 * shares its addresses with SGMII GMAC_4, which was
354 * set in the caller. */
364 * All our knowledge of chip and board that cannot be detected by probing
365 * at run-time goes here
368 xlr_board_info_setup()
370 struct xlr_gmac_block_t *blk0, *blk1, *blk2;
371 struct xlr_i2c_dev_t* iic_blk;
374 /* This setup code is long'ish because the same base driver
375 * (if_nlge.c) is used for different:
377 * - boards (for each CPU, multiple board configs are possible
380 * At the time of writing, there are atleast 12 boards, 4 with XLR
381 * and 8 with XLS. This means that the base driver needs to work with
382 * 12 different configurations, with varying levels of differences.
383 * To accomodate the different configs, the xlr_board_info struct
384 * has various attributes for paramters that could be different.
385 * These attributes are setup here and can be used directly in the
387 * It was seen that the setup code is not entirely trivial and
388 * it is possible to organize it in different ways. In the following,
389 * we choose an approach that sacrifices code-compactness/speed for
390 * readability. This is because configuration code executes once
391 * per reboot and hence has a minimal performance impact.
392 * On the other hand, driver debugging/enhancements require
393 * that different engineers can quickly comprehend the setup
394 * sequence. Hence, readability is seen as the key requirement for
395 * this code. It is for the reader to decide how much of this
396 * requirement is met with the current code organization !!
398 * The initialization is organized thus:
401 * // initialize per XLS architecture
402 * // default inits (per chip spec)
403 * // chip-specific overrides
404 * // board-specific overrides
405 * } else if (CPU is XLR) {
406 * // initialize per XLR architecture
407 * // default inits (per chip spec)
408 * // chip-specific overrides
409 * // board-specific overrides
412 * For each CPU family, all the default initializations
413 * are done for a fully-loaded device of that family.
414 * This configuration is then adjusted for the actual
415 * chip id. This is followed up with board specific
419 /* start with a clean slate */
420 memset(&xlr_board_info, 0, sizeof(xlr_board_info));
421 xlr_board_info.ata = xlr_pcmcia_present();
423 blk0 = &xlr_board_info.gmac_block[0];
424 blk1 = &xlr_board_info.gmac_block[1];
425 blk2 = &xlr_board_info.gmac_block[2];
427 iic_blk = xlr_board_info.xlr_i2c_device;
428 iic_blk[I2C_RTC].enabled = 1;
429 iic_blk[I2C_RTC].addr = XLR_I2C_RTC_ADDR;
430 iic_blk[I2C_THERMAL].enabled = 1;
431 iic_blk[I2C_THERMAL].addr = XLR_I2C_TEMPSENSOR_ADDR;
432 iic_blk[I2C_EEPROM].enabled = 1;
433 iic_blk[I2C_EEPROM].addr = XLR_I2C_EEPROM_ADDR;
436 xlr_board_info.is_xls = 1;
437 xlr_board_info.nr_cpus = 8;
438 xlr_board_info.usb = 1;
439 /* Board version 8 has NAND flash */
441 (xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII);
442 xlr_board_info.pci_irq = 0;
443 xlr_board_info.credit_configs = xls_core_cc_configs;
444 xlr_board_info.bucket_sizes = &xls_bucket_sizes;
445 xlr_board_info.gmacports = MAX_NA_PORTS;
447 /* ---------------- Network Acc 0 ---------------- */
449 blk0->type = XLR_GMAC;
451 blk0->credit_config = &xls_cc_table_gmac0;
452 blk0->station_id = MSGRNG_STNID_GMAC;
453 blk0->station_txbase = MSGRNG_STNID_GMACTX0;
454 blk0->station_rfr = MSGRNG_STNID_GMACRFR_0;
455 blk0->mode = XLR_SGMII;
456 blk0->baseaddr = XLR_IO_GMAC_0_OFFSET;
457 blk0->baseirq = PIC_GMAC_0_IRQ;
460 /* By default, assume SGMII is setup. But this can change based
461 on board-specific or setting-specific info. */
462 for (i = 0; i < 4; i++) {
463 blk0->gmac_port[i].valid = 1;
464 blk0->gmac_port[i].instance = i + blk0->baseinst;
465 blk0->gmac_port[i].type = XLR_SGMII;
466 blk0->gmac_port[i].phy_addr = i + 16;
467 blk0->gmac_port[i].tx_bucket_id =
468 blk0->station_txbase + i;
469 blk0->gmac_port[i].mdint_id = 0;
471 blk0->gmac_port[i].base_addr = XLR_IO_GMAC_0_OFFSET + i * 0x1000;
472 blk0->gmac_port[i].mii_addr = XLR_IO_GMAC_0_OFFSET;
473 blk0->gmac_port[i].pcs_addr = XLR_IO_GMAC_0_OFFSET;
474 blk0->gmac_port[i].serdes_addr = XLR_IO_GMAC_0_OFFSET;
477 /* ---------------- Network Acc 1 ---------------- */
478 blk1->type = XLR_GMAC;
480 blk1->credit_config = &xls_cc_table_gmac1;
481 blk1->station_id = MSGRNG_STNID_GMAC1;
482 blk1->station_txbase = MSGRNG_STNID_GMAC1_TX0;
483 blk1->station_rfr = MSGRNG_STNID_GMAC1_FR_0;
484 blk1->mode = XLR_SGMII;
485 blk1->baseaddr = XLR_IO_GMAC_4_OFFSET;
486 blk1->baseirq = PIC_XGS_0_IRQ;
489 for (i = 0; i < 4; i++) {
490 blk1->gmac_port[i].valid = 1;
491 blk1->gmac_port[i].instance = i + blk1->baseinst;
492 blk1->gmac_port[i].type = XLR_SGMII;
493 blk1->gmac_port[i].phy_addr = i + 20;
494 blk1->gmac_port[i].tx_bucket_id =
495 blk1->station_txbase + i;
496 blk1->gmac_port[i].mdint_id = 1;
498 blk1->gmac_port[i].base_addr = XLR_IO_GMAC_4_OFFSET + i * 0x1000;
499 blk1->gmac_port[i].mii_addr = XLR_IO_GMAC_4_OFFSET;
500 blk1->gmac_port[i].pcs_addr = XLR_IO_GMAC_4_OFFSET;
501 blk1->gmac_port[i].serdes_addr = XLR_IO_GMAC_0_OFFSET;
504 /* ---------------- Network Acc 2 ---------------- */
505 xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */
507 xls_chip_specific_overrides(&xlr_board_info);
508 xls_board_specific_overrides(&xlr_board_info);
511 xlr_board_info.is_xls = 0;
512 xlr_board_info.nr_cpus = 32;
513 xlr_board_info.usb = 0;
514 xlr_board_info.cfi = 1;
515 xlr_board_info.pci_irq = 0;
516 xlr_board_info.credit_configs = xlr_core_cc_configs;
517 xlr_board_info.bucket_sizes = &bucket_sizes;
518 xlr_board_info.gmacports = 4;
520 /* ---------------- GMAC0 ---------------- */
521 blk0->type = XLR_GMAC;
523 blk0->credit_config = &cc_table_gmac;
524 blk0->station_id = MSGRNG_STNID_GMAC;
525 blk0->station_txbase = MSGRNG_STNID_GMACTX0;
526 blk0->station_rfr = MSGRNG_STNID_GMACRFR_0;
527 blk0->mode = XLR_RGMII;
528 blk0->baseaddr = XLR_IO_GMAC_0_OFFSET;
529 blk0->baseirq = PIC_GMAC_0_IRQ;
532 /* first, do the common/easy stuff for all the ports */
533 for (i = 0; i < 4; i++) {
534 blk0->gmac_port[i].valid = 1;
535 blk0->gmac_port[i].instance = i + blk0->baseinst;
536 blk0->gmac_port[i].type = XLR_RGMII;
537 blk0->gmac_port[i].phy_addr = i;
538 blk0->gmac_port[i].tx_bucket_id =
539 blk0->station_txbase + i;
540 blk0->gmac_port[i].mdint_id = 0;
541 blk0->gmac_port[i].base_addr = XLR_IO_GMAC_0_OFFSET + i * 0x1000;
542 blk0->gmac_port[i].mii_addr = XLR_IO_GMAC_0_OFFSET;
543 /* RGMII ports, no PCS/SERDES */
547 /* ---------------- XGMAC0 ---------------- */
548 blk1->type = XLR_XGMAC;
549 blk1->mode = XLR_XGMII;
551 blk1->credit_config = &cc_table_xgs_0;
552 blk1->station_txbase = MSGRNG_STNID_XGS0_TX;
553 blk1->station_rfr = MSGRNG_STNID_XMAC0RFR;
554 blk1->station_id = MSGRNG_STNID_XGS0FR;
555 blk1->baseaddr = XLR_IO_XGMAC_0_OFFSET;
556 blk1->baseirq = PIC_XGS_0_IRQ;
559 blk1->gmac_port[0].type = XLR_XGMII;
560 blk1->gmac_port[0].instance = 0;
561 blk1->gmac_port[0].phy_addr = 0;
562 blk1->gmac_port[0].base_addr = XLR_IO_XGMAC_0_OFFSET;
563 blk1->gmac_port[0].mii_addr = XLR_IO_XGMAC_0_OFFSET;
564 blk1->gmac_port[0].tx_bucket_id = blk1->station_txbase;
565 blk1->gmac_port[0].mdint_id = 1;
567 /* ---------------- XGMAC1 ---------------- */
568 blk2->type = XLR_XGMAC;
569 blk2->mode = XLR_XGMII;
571 blk2->credit_config = &cc_table_xgs_1;
572 blk2->station_txbase = MSGRNG_STNID_XGS1_TX;
573 blk2->station_rfr = MSGRNG_STNID_XMAC1RFR;
574 blk2->station_id = MSGRNG_STNID_XGS1FR;
575 blk2->baseaddr = XLR_IO_XGMAC_1_OFFSET;
576 blk2->baseirq = PIC_XGS_1_IRQ;
579 blk2->gmac_port[0].type = XLR_XGMII;
580 blk2->gmac_port[0].instance = 0;
581 blk2->gmac_port[0].phy_addr = 0;
582 blk2->gmac_port[0].base_addr = XLR_IO_XGMAC_1_OFFSET;
583 blk2->gmac_port[0].mii_addr = XLR_IO_XGMAC_1_OFFSET;
584 blk2->gmac_port[0].tx_bucket_id = blk2->station_txbase;
585 blk2->gmac_port[0].mdint_id = 2;
587 /* Done with default setup. Now handle chip and board-specific
589 xlr_chip_specific_overrides(&xlr_board_info);
590 xlr_board_specific_overrides(&xlr_board_info);