board.c revision 211946
1/********************************************************************* 2 * 3 * Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). All rights 4 * reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 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 15 * distribution. 16 * 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. 28 * 29 * *****************************RMI_2**********************************/ 30#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31__FBSDID("$FreeBSD: head/sys/mips/rmi/board.c 211946 2010-08-28 19:02:51Z jchandra $"); 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/kernel.h> 36#include <sys/lock.h> 37#include <sys/mutex.h> 38 39#include <machine/cpufunc.h> 40#include <mips/rmi/msgring.h> 41#include <mips/rmi/board.h> 42#include <mips/rmi/pic.h> 43#include <mips/rmi/shared_structs.h> 44 45static int xlr_rxstn_to_txstn_map[128] = { 46 [0 ... 7] = TX_STN_CPU_0, 47 [8 ... 15] = TX_STN_CPU_1, 48 [16 ... 23] = TX_STN_CPU_2, 49 [24 ... 31] = TX_STN_CPU_3, 50 [32 ... 39] = TX_STN_CPU_4, 51 [40 ... 47] = TX_STN_CPU_5, 52 [48 ... 55] = TX_STN_CPU_6, 53 [56 ... 63] = TX_STN_CPU_7, 54 [64 ... 95] = TX_STN_INVALID, 55 [96 ... 103] = TX_STN_GMAC, 56 [104 ... 107] = TX_STN_DMA, 57 [108 ... 111] = TX_STN_INVALID, 58 [112 ... 113] = TX_STN_XGS_0, 59 [114 ... 115] = TX_STN_XGS_1, 60 [116 ... 119] = TX_STN_INVALID, 61 [120 ... 127] = TX_STN_SAE 62}; 63 64static int xls_rxstn_to_txstn_map[128] = { 65 [0 ... 7] = TX_STN_CPU_0, 66 [8 ... 15] = TX_STN_CPU_1, 67 [16 ... 23] = TX_STN_CPU_2, 68 [24 ... 31] = TX_STN_CPU_3, 69 [32 ... 63] = TX_STN_INVALID, 70 [64 ... 71] = TX_STN_PCIE, 71 [72 ... 79] = TX_STN_INVALID, 72 [80 ... 87] = TX_STN_GMAC1, 73 [88 ... 95] = TX_STN_INVALID, 74 [96 ... 103] = TX_STN_GMAC0, 75 [104 ... 107] = TX_STN_DMA, 76 [108 ... 111] = TX_STN_CDE, 77 [112 ... 119] = TX_STN_INVALID, 78 [120 ... 127] = TX_STN_SAE 79}; 80 81struct stn_cc *xlr_core_cc_configs[] = { &cc_table_cpu_0, &cc_table_cpu_1, 82 &cc_table_cpu_2, &cc_table_cpu_3, &cc_table_cpu_4, &cc_table_cpu_5, 83 &cc_table_cpu_6, &cc_table_cpu_7}; 84 85struct stn_cc *xls_core_cc_configs[] = { &xls_cc_table_cpu_0, &xls_cc_table_cpu_1, 86 &xls_cc_table_cpu_2, &xls_cc_table_cpu_3 }; 87 88struct xlr_board_info xlr_board_info; 89 90static int 91xlr_pcmcia_present(void) 92{ 93 xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_GPIO_OFFSET); 94 uint32_t resetconf; 95 96 resetconf = xlr_read_reg(mmio, 21); 97 return ((resetconf & 0x4000) != 0); 98} 99 100static void 101xlr_board_specific_overrides(struct xlr_board_info* board) 102{ 103 struct xlr_gmac_block_t *blk1, *blk2; 104 105 blk1 = &board->gmac_block[1]; 106 blk2 = &board->gmac_block[2]; 107 108 switch (xlr_boot1_info.board_major_version) { 109 case RMI_XLR_BOARD_ARIZONA_I: 110 /* ATX-I has SPI-4, not XGMAC */ 111 blk1->type = XLR_SPI4; 112 blk1->enabled = 0; /* nlge does not 113 support SPI-4 */ 114 blk2->type = XLR_SPI4; 115 blk2->enabled = 0; 116 break; 117 118 case RMI_XLR_BOARD_ARIZONA_II: 119 /* XGMII_A --> VSC7281, XGMII_B --> VSC7281 */ 120 blk1->enabled = 1; 121 blk1->num_ports = 1; 122 blk1->gmac_port[0].valid = 1; 123 124 blk2->enabled = 1; 125 blk2->num_ports = 1; 126 blk2->gmac_port[0].valid = 1; 127 default: 128 break; 129 } 130} 131 132static int 133quad0_xaui(void) 134{ 135 xlr_reg_t *gpio_mmio = 136 (unsigned int *)(DEFAULT_XLR_IO_BASE + XLR_IO_GPIO_OFFSET); 137 uint32_t bit24; 138 139 bit24 = (xlr_read_reg(gpio_mmio, 0x15) >> 24) & 0x1; 140 return (bit24); 141} 142 143static int 144quad1_xaui(void) 145{ 146 xlr_reg_t *gpio_mmio = 147 (unsigned int *)(DEFAULT_XLR_IO_BASE + XLR_IO_GPIO_OFFSET); 148 uint32_t bit25; 149 150 bit25 = (xlr_read_reg(gpio_mmio, 0x15) >> 25) & 0x1; 151 return (bit25); 152} 153 154static void 155xls_board_specific_overrides(struct xlr_board_info* board) 156{ 157 struct xlr_gmac_block_t *blk0, *blk1; 158 int i; 159 160 blk0 = &board->gmac_block[0]; 161 blk1 = &board->gmac_block[1]; 162 163 switch (xlr_boot1_info.board_major_version) { 164 case RMI_XLR_BOARD_ARIZONA_VI: 165 blk0->mode = XLR_PORT0_RGMII; 166 blk0->gmac_port[0].type = XLR_RGMII; 167 blk0->gmac_port[0].phy_addr = 0; 168 blk0->gmac_port[0].mii_addr = XLR_IO_GMAC_4_OFFSET; 169 /* Because of the Octal PHY, SGMII Quad1 is MII is also bound 170 * to the PHY attached to SGMII0_MDC/MDIO/MDINT. */ 171 for (i = 0; i < 4; i++) { 172 blk1->gmac_port[i].mii_addr = XLR_IO_GMAC_0_OFFSET; 173 blk1->gmac_port[i].serdes_addr = XLR_IO_GMAC_0_OFFSET; 174 } 175 blk1->gmac_port[1].mii_addr = XLR_IO_GMAC_0_OFFSET; 176 blk1->gmac_port[2].mii_addr = XLR_IO_GMAC_0_OFFSET; 177 blk1->gmac_port[3].mii_addr = XLR_IO_GMAC_0_OFFSET; 178 179 blk1->gmac_port[1].serdes_addr = XLR_IO_GMAC_0_OFFSET; 180 blk1->gmac_port[2].serdes_addr = XLR_IO_GMAC_0_OFFSET; 181 blk1->gmac_port[3].serdes_addr = XLR_IO_GMAC_0_OFFSET; 182 183 /* RGMII MDIO interrupt is thru NA1 and SGMII MDIO 184 * interrupts for ports in blk1 are from NA0 */ 185 blk0->gmac_port[0].mdint_id = 1; 186 187 blk1->gmac_port[0].mdint_id = 0; 188 blk1->gmac_port[1].mdint_id = 0; 189 blk1->gmac_port[2].mdint_id = 0; 190 blk1->gmac_port[3].mdint_id = 0; 191 break; 192 193 case RMI_XLR_BOARD_ARIZONA_VIII: 194 /* There is just one Octal PHY on the board and it is 195 * connected to the MII interface for NA Quad 0. */ 196 blk1->gmac_port[0].mii_addr = XLR_IO_GMAC_0_OFFSET; 197 blk1->gmac_port[1].mii_addr = XLR_IO_GMAC_0_OFFSET; 198 blk1->gmac_port[2].mii_addr = XLR_IO_GMAC_0_OFFSET; 199 blk1->gmac_port[3].mii_addr = XLR_IO_GMAC_0_OFFSET; 200 201 /* Board 8.3 (Lite) has XLS108 */ 202 if (xlr_boot1_info.board_minor_version == 3) { 203 /* NA0 has 3 ports */ 204 blk0->gmac_port[3].valid = 1; 205 blk0->num_ports--; 206 /* NA1 is completely disabled */ 207 blk1->enabled = 0; 208 } 209 210 break; 211 212 case RMI_XLR_BOARD_ARIZONA_XI: 213 case RMI_XLR_BOARD_ARIZONA_XII: 214 if (quad0_xaui()) { /* GMAC ports 0-3 are set to XAUI */ 215 /* only GMAC0 is active i.e, the 0-th port on this quad. 216 * Disable all the other 7 possible ports. */ 217 for (i = 1; i < MAX_NA_PORTS; i++) { 218 memset(&blk0->gmac_port[i], 0, 219 sizeof(blk0->gmac_port[i])); 220 } 221 /* Setup for XAUI on N/w Acc0: gmac0 */ 222 blk0->type = XLR_XGMAC; 223 blk0->mode = XLR_XAUI; 224 blk0->num_ports = 1; 225 blk0->gmac_port[0].type = XLR_XAUI; 226 blk1->gmac_port[0].phy_addr = 16; 227 blk0->gmac_port[0].tx_bucket_id = blk0->station_txbase; 228 /* Other addresses etc need not be modified as XAUI_0 229 * shares its addresses with SGMII GMAC_0, which was 230 * set in the caller. */ 231 } 232 else { 233 blk0->num_ports = 1; /* only 1 RGMII port */ 234 blk0->mode = XLR_PORT0_RGMII; 235 blk0->gmac_port[0].type = XLR_RGMII; 236 blk0->gmac_port[0].phy_addr = 0; 237 blk0->gmac_port[0].mii_addr = XLR_IO_GMAC_0_OFFSET; 238 } 239 240 if (quad1_xaui()) { /* GMAC ports 4-7 are used for XAUI */ 241 /* only GMAC4 is active i.e, the 0-th port on this quad. 242 * Disable all the other 7 possible ports. */ 243 for (i = 1; i < MAX_NA_PORTS; i++) { 244 memset(&blk1->gmac_port[i], 0, 245 sizeof(blk1->gmac_port[i])); 246 } 247 /* Setup for XAUI on N/w Acc1: gmac4 */ 248 blk1->type = XLR_XGMAC; 249 blk1->mode = XLR_XAUI; 250 blk1->num_ports = 1; 251 /* XAUI and SGMII ports share FMN buckets on N/w Acc 1; 252 so, station_txbase, station_rfr need not be 253 patched up. */ 254 blk1->gmac_port[0].type = XLR_XAUI; 255 blk1->gmac_port[0].phy_addr = 16; 256 blk1->gmac_port[0].tx_bucket_id = blk1->station_txbase; 257 /* Other addresses etc need not be modified as XAUI_1 258 * shares its addresses with SGMII GMAC_4, which was 259 * set in the caller. */ 260 } 261 break; 262 263 default: 264 break; 265 } 266} 267 268/* 269 * All our knowledge of chip and board that cannot be detected by probing 270 * at run-time goes here 271 */ 272int 273xlr_board_info_setup() 274{ 275 struct xlr_gmac_block_t *blk0, *blk1, *blk2; 276 int i; 277 278 /* This setup code is long'ish because the same base driver 279 * (if_nlge.c) is used for different: 280 * - CPUs (XLR/XLS) 281 * - boards (for each CPU, multiple board configs are possible 282 * and available). 283 * 284 * At the time of writing, there are atleast 12 boards, 4 with XLR 285 * and 8 with XLS. This means that the base driver needs to work with 286 * 12 different configurations, with varying levels of differences. 287 * To accomodate the different configs, the xlr_board_info struct 288 * has various attributes for paramters that could be different. 289 * These attributes are setup here and can be used directly in the 290 * base driver. 291 * It was seen that the setup code is not entirely trivial and 292 * it is possible to organize it in different ways. In the following, 293 * we choose an approach that sacrifices code-compactness/speed for 294 * readability. This is because configuration code executes once 295 * per reboot and hence has a minimal performance impact. 296 * On the other hand, driver debugging/enhancements require 297 * that different engineers can quickly comprehend the setup 298 * sequence. Hence, readability is seen as the key requirement for 299 * this code. It is for the reader to decide how much of this 300 * requirement is met with the current code organization !! 301 * 302 * The initialization is organized thus: 303 * 304 * if (CPU is XLS) { 305 * // initialize per XLS architecture 306 * // default inits (per chip spec) 307 * // board-specific overrides 308 * } else if (CPU is XLR) { 309 * // initialize per XLR architecture 310 * // default inits (per chip spec) 311 * // board-specific overrides 312 * } 313 * 314 * Within each CPU-specific initialization, all the default 315 * initializations are done first. This is followed up with 316 * board specific overrides. 317 */ 318 319 /* start with a clean slate */ 320 memset(&xlr_board_info, 0, sizeof(xlr_board_info)); 321 xlr_board_info.ata = xlr_pcmcia_present(); 322 323 blk0 = &xlr_board_info.gmac_block[0]; 324 blk1 = &xlr_board_info.gmac_block[1]; 325 blk2 = &xlr_board_info.gmac_block[2]; 326 327 if (xlr_is_xls()) { 328 xlr_board_info.is_xls = 1; 329 xlr_board_info.nr_cpus = 8; 330 xlr_board_info.usb = 1; 331 /* Board version 8 has NAND flash */ 332 xlr_board_info.cfi = 333 (xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII); 334 xlr_board_info.pci_irq = 0; 335 xlr_board_info.credit_configs = xls_core_cc_configs; 336 xlr_board_info.bucket_sizes = &xls_bucket_sizes; 337 xlr_board_info.msgmap = xls_rxstn_to_txstn_map; 338 xlr_board_info.gmacports = MAX_NA_PORTS; 339 340 /* ---------------- Network Acc 0 ---------------- */ 341 342 blk0->type = XLR_GMAC; 343 blk0->enabled = 0xf; 344 blk0->credit_config = &xls_cc_table_gmac0; 345 blk0->station_id = TX_STN_GMAC0; 346 blk0->station_txbase = MSGRNG_STNID_GMACTX0; 347 blk0->station_rfr = MSGRNG_STNID_GMACRFR_0; 348 blk0->mode = XLR_SGMII; 349 blk0->baseaddr = XLR_IO_GMAC_0_OFFSET; 350 blk0->baseirq = PIC_GMAC_0_IRQ; 351 blk0->baseinst = 0; 352 353 /* By default, assume SGMII is setup. But this can change based 354 on board-specific or setting-specific info. */ 355 for (i = 0; i < 4; i++) { 356 blk0->gmac_port[i].valid = 1; 357 blk0->gmac_port[i].instance = i + blk0->baseinst; 358 blk0->gmac_port[i].type = XLR_SGMII; 359 blk0->gmac_port[i].phy_addr = i + 16; 360 blk0->gmac_port[i].tx_bucket_id = 361 blk0->station_txbase + i; 362 blk0->gmac_port[i].mdint_id = 0; 363 blk0->num_ports++; 364 blk0->gmac_port[i].base_addr = XLR_IO_GMAC_0_OFFSET + i * 0x1000; 365 blk0->gmac_port[i].mii_addr = XLR_IO_GMAC_0_OFFSET; 366 blk0->gmac_port[i].pcs_addr = XLR_IO_GMAC_0_OFFSET; 367 blk0->gmac_port[i].serdes_addr = XLR_IO_GMAC_0_OFFSET; 368 } 369 370 /* ---------------- Network Acc 1 ---------------- */ 371 blk1->type = XLR_GMAC; 372 blk1->enabled = 0xf; 373 blk1->credit_config = &xls_cc_table_gmac1; 374 blk1->station_id = TX_STN_GMAC1; 375 blk1->station_txbase = MSGRNG_STNID_GMAC1_TX0; 376 blk1->station_rfr = MSGRNG_STNID_GMAC1_FR_0; 377 blk1->mode = XLR_SGMII; 378 blk1->baseaddr = XLR_IO_GMAC_4_OFFSET; 379 blk1->baseirq = PIC_XGS_0_IRQ; 380 blk1->baseinst = 4; 381 382 for (i = 0; i < 4; i++) { 383 blk1->gmac_port[i].valid = 1; 384 blk1->gmac_port[i].instance = i + blk1->baseinst; 385 blk1->gmac_port[i].type = XLR_SGMII; 386 blk1->gmac_port[i].phy_addr = i + 20; 387 blk1->gmac_port[i].tx_bucket_id = 388 blk1->station_txbase + i; 389 blk1->gmac_port[i].mdint_id = 1; 390 blk1->num_ports++; 391 blk1->gmac_port[i].base_addr = XLR_IO_GMAC_4_OFFSET + i * 0x1000; 392 blk1->gmac_port[i].mii_addr = XLR_IO_GMAC_4_OFFSET; 393 blk1->gmac_port[i].pcs_addr = XLR_IO_GMAC_4_OFFSET; 394 blk1->gmac_port[i].serdes_addr = XLR_IO_GMAC_0_OFFSET; 395 } 396 397 /* ---------------- Network Acc 2 ---------------- */ 398 xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */ 399 400 xls_board_specific_overrides(&xlr_board_info); 401 402 } else { /* XLR */ 403 xlr_board_info.is_xls = 0; 404 xlr_board_info.nr_cpus = 32; 405 xlr_board_info.usb = 0; 406 xlr_board_info.cfi = 1; 407 xlr_board_info.pci_irq = 0; 408 xlr_board_info.credit_configs = xlr_core_cc_configs; 409 xlr_board_info.bucket_sizes = &bucket_sizes; 410 xlr_board_info.msgmap = xlr_rxstn_to_txstn_map; 411 xlr_board_info.gmacports = 4; 412 413 /* ---------------- GMAC0 ---------------- */ 414 blk0->type = XLR_GMAC; 415 blk0->enabled = 0xf; 416 blk0->credit_config = &cc_table_gmac; 417 blk0->station_id = TX_STN_GMAC; 418 blk0->station_txbase = MSGRNG_STNID_GMACTX0; 419 blk0->station_rfr = MSGRNG_STNID_GMACRFR_0; 420 blk0->mode = XLR_RGMII; 421 blk0->baseaddr = XLR_IO_GMAC_0_OFFSET; 422 blk0->baseirq = PIC_GMAC_0_IRQ; 423 blk0->baseinst = 0; 424 425 /* first, do the common/easy stuff for all the ports */ 426 for (i = 0; i < 4; i++) { 427 blk0->gmac_port[i].valid = 1; 428 blk0->gmac_port[i].instance = i + blk0->baseinst; 429 blk0->gmac_port[i].type = XLR_RGMII; 430 blk0->gmac_port[i].phy_addr = i; 431 blk0->gmac_port[i].tx_bucket_id = 432 blk0->station_txbase + i; 433 blk0->gmac_port[i].mdint_id = 0; 434 blk0->gmac_port[i].base_addr = XLR_IO_GMAC_0_OFFSET + i * 0x1000; 435 blk0->gmac_port[i].mii_addr = XLR_IO_GMAC_0_OFFSET; 436 /* RGMII ports, no PCS/SERDES */ 437 blk0->num_ports++; 438 } 439 440 /* ---------------- XGMAC0 ---------------- */ 441 blk1->type = XLR_XGMAC; 442 blk1->mode = XLR_XGMII; 443 blk1->enabled = 0; 444 blk1->credit_config = &cc_table_xgs_0; 445 blk1->station_txbase = MSGRNG_STNID_XGS0_TX; 446 blk1->station_rfr = MSGRNG_STNID_XMAC0RFR; 447 blk1->station_id = TX_STN_XGS_0; /* TBD: is this correct ? */ 448 blk1->baseaddr = XLR_IO_XGMAC_0_OFFSET; 449 blk1->baseirq = PIC_XGS_0_IRQ; 450 blk1->baseinst = 4; 451 452 blk1->gmac_port[0].type = XLR_XGMII; 453 blk1->gmac_port[0].instance = 0; 454 blk1->gmac_port[0].phy_addr = 0; 455 blk1->gmac_port[0].base_addr = XLR_IO_XGMAC_0_OFFSET; 456 blk1->gmac_port[0].mii_addr = XLR_IO_XGMAC_0_OFFSET; 457 blk1->gmac_port[0].tx_bucket_id = blk1->station_txbase; 458 blk1->gmac_port[0].mdint_id = 1; 459 460 /* ---------------- XGMAC1 ---------------- */ 461 blk2->type = XLR_XGMAC; 462 blk2->mode = XLR_XGMII; 463 blk2->enabled = 0; 464 blk2->credit_config = &cc_table_xgs_1; 465 blk2->station_txbase = MSGRNG_STNID_XGS1_TX; 466 blk2->station_rfr = MSGRNG_STNID_XMAC1RFR; 467 blk2->station_id = TX_STN_XGS_1; /* TBD: is this correct ? */ 468 blk2->baseaddr = XLR_IO_XGMAC_1_OFFSET; 469 blk2->baseirq = PIC_XGS_1_IRQ; 470 blk2->baseinst = 5; 471 472 blk2->gmac_port[0].type = XLR_XGMII; 473 blk2->gmac_port[0].instance = 0; 474 blk2->gmac_port[0].phy_addr = 0; 475 blk2->gmac_port[0].base_addr = XLR_IO_XGMAC_1_OFFSET; 476 blk2->gmac_port[0].mii_addr = XLR_IO_XGMAC_1_OFFSET; 477 blk2->gmac_port[0].tx_bucket_id = blk2->station_txbase; 478 blk2->gmac_port[0].mdint_id = 2; 479 480 /* Done with default setup. Now do board-specific tweaks. */ 481 xlr_board_specific_overrides(&xlr_board_info); 482 } 483 return 0; 484} 485