1/* 2 * Copyright (c) 2003-2012 Broadcom Corporation 3 * All Rights Reserved 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the Broadcom 9 * license below: 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#ifndef _NLM_FMN_H_ 36#define _NLM_FMN_H_ 37 38#include <asm/netlogic/mips-extns.h> /* for COP2 access */ 39 40/* Station IDs */ 41#define FMN_STNID_CPU0 0x00 42#define FMN_STNID_CPU1 0x08 43#define FMN_STNID_CPU2 0x10 44#define FMN_STNID_CPU3 0x18 45#define FMN_STNID_CPU4 0x20 46#define FMN_STNID_CPU5 0x28 47#define FMN_STNID_CPU6 0x30 48#define FMN_STNID_CPU7 0x38 49 50#define FMN_STNID_XGS0_TX 64 51#define FMN_STNID_XMAC0_00_TX 64 52#define FMN_STNID_XMAC0_01_TX 65 53#define FMN_STNID_XMAC0_02_TX 66 54#define FMN_STNID_XMAC0_03_TX 67 55#define FMN_STNID_XMAC0_04_TX 68 56#define FMN_STNID_XMAC0_05_TX 69 57#define FMN_STNID_XMAC0_06_TX 70 58#define FMN_STNID_XMAC0_07_TX 71 59#define FMN_STNID_XMAC0_08_TX 72 60#define FMN_STNID_XMAC0_09_TX 73 61#define FMN_STNID_XMAC0_10_TX 74 62#define FMN_STNID_XMAC0_11_TX 75 63#define FMN_STNID_XMAC0_12_TX 76 64#define FMN_STNID_XMAC0_13_TX 77 65#define FMN_STNID_XMAC0_14_TX 78 66#define FMN_STNID_XMAC0_15_TX 79 67 68#define FMN_STNID_XGS1_TX 80 69#define FMN_STNID_XMAC1_00_TX 80 70#define FMN_STNID_XMAC1_01_TX 81 71#define FMN_STNID_XMAC1_02_TX 82 72#define FMN_STNID_XMAC1_03_TX 83 73#define FMN_STNID_XMAC1_04_TX 84 74#define FMN_STNID_XMAC1_05_TX 85 75#define FMN_STNID_XMAC1_06_TX 86 76#define FMN_STNID_XMAC1_07_TX 87 77#define FMN_STNID_XMAC1_08_TX 88 78#define FMN_STNID_XMAC1_09_TX 89 79#define FMN_STNID_XMAC1_10_TX 90 80#define FMN_STNID_XMAC1_11_TX 91 81#define FMN_STNID_XMAC1_12_TX 92 82#define FMN_STNID_XMAC1_13_TX 93 83#define FMN_STNID_XMAC1_14_TX 94 84#define FMN_STNID_XMAC1_15_TX 95 85 86#define FMN_STNID_GMAC 96 87#define FMN_STNID_GMACJFR_0 96 88#define FMN_STNID_GMACRFR_0 97 89#define FMN_STNID_GMACTX0 98 90#define FMN_STNID_GMACTX1 99 91#define FMN_STNID_GMACTX2 100 92#define FMN_STNID_GMACTX3 101 93#define FMN_STNID_GMACJFR_1 102 94#define FMN_STNID_GMACRFR_1 103 95 96#define FMN_STNID_DMA 104 97#define FMN_STNID_DMA_0 104 98#define FMN_STNID_DMA_1 105 99#define FMN_STNID_DMA_2 106 100#define FMN_STNID_DMA_3 107 101 102#define FMN_STNID_XGS0FR 112 103#define FMN_STNID_XMAC0JFR 112 104#define FMN_STNID_XMAC0RFR 113 105 106#define FMN_STNID_XGS1FR 114 107#define FMN_STNID_XMAC1JFR 114 108#define FMN_STNID_XMAC1RFR 115 109#define FMN_STNID_SEC 120 110#define FMN_STNID_SEC0 120 111#define FMN_STNID_SEC1 121 112#define FMN_STNID_SEC2 122 113#define FMN_STNID_SEC3 123 114#define FMN_STNID_PK0 124 115#define FMN_STNID_SEC_RSA 124 116#define FMN_STNID_SEC_RSVD0 125 117#define FMN_STNID_SEC_RSVD1 126 118#define FMN_STNID_SEC_RSVD2 127 119 120#define FMN_STNID_GMAC1 80 121#define FMN_STNID_GMAC1_FR_0 81 122#define FMN_STNID_GMAC1_TX0 82 123#define FMN_STNID_GMAC1_TX1 83 124#define FMN_STNID_GMAC1_TX2 84 125#define FMN_STNID_GMAC1_TX3 85 126#define FMN_STNID_GMAC1_FR_1 87 127#define FMN_STNID_GMAC0 96 128#define FMN_STNID_GMAC0_FR_0 97 129#define FMN_STNID_GMAC0_TX0 98 130#define FMN_STNID_GMAC0_TX1 99 131#define FMN_STNID_GMAC0_TX2 100 132#define FMN_STNID_GMAC0_TX3 101 133#define FMN_STNID_GMAC0_FR_1 103 134#define FMN_STNID_CMP_0 108 135#define FMN_STNID_CMP_1 109 136#define FMN_STNID_CMP_2 110 137#define FMN_STNID_CMP_3 111 138#define FMN_STNID_PCIE_0 116 139#define FMN_STNID_PCIE_1 117 140#define FMN_STNID_PCIE_2 118 141#define FMN_STNID_PCIE_3 119 142#define FMN_STNID_XLS_PK0 121 143 144#define nlm_read_c2_cc0(s) __read_32bit_c2_register($16, s) 145#define nlm_read_c2_cc1(s) __read_32bit_c2_register($17, s) 146#define nlm_read_c2_cc2(s) __read_32bit_c2_register($18, s) 147#define nlm_read_c2_cc3(s) __read_32bit_c2_register($19, s) 148#define nlm_read_c2_cc4(s) __read_32bit_c2_register($20, s) 149#define nlm_read_c2_cc5(s) __read_32bit_c2_register($21, s) 150#define nlm_read_c2_cc6(s) __read_32bit_c2_register($22, s) 151#define nlm_read_c2_cc7(s) __read_32bit_c2_register($23, s) 152#define nlm_read_c2_cc8(s) __read_32bit_c2_register($24, s) 153#define nlm_read_c2_cc9(s) __read_32bit_c2_register($25, s) 154#define nlm_read_c2_cc10(s) __read_32bit_c2_register($26, s) 155#define nlm_read_c2_cc11(s) __read_32bit_c2_register($27, s) 156#define nlm_read_c2_cc12(s) __read_32bit_c2_register($28, s) 157#define nlm_read_c2_cc13(s) __read_32bit_c2_register($29, s) 158#define nlm_read_c2_cc14(s) __read_32bit_c2_register($30, s) 159#define nlm_read_c2_cc15(s) __read_32bit_c2_register($31, s) 160 161#define nlm_write_c2_cc0(s, v) __write_32bit_c2_register($16, s, v) 162#define nlm_write_c2_cc1(s, v) __write_32bit_c2_register($17, s, v) 163#define nlm_write_c2_cc2(s, v) __write_32bit_c2_register($18, s, v) 164#define nlm_write_c2_cc3(s, v) __write_32bit_c2_register($19, s, v) 165#define nlm_write_c2_cc4(s, v) __write_32bit_c2_register($20, s, v) 166#define nlm_write_c2_cc5(s, v) __write_32bit_c2_register($21, s, v) 167#define nlm_write_c2_cc6(s, v) __write_32bit_c2_register($22, s, v) 168#define nlm_write_c2_cc7(s, v) __write_32bit_c2_register($23, s, v) 169#define nlm_write_c2_cc8(s, v) __write_32bit_c2_register($24, s, v) 170#define nlm_write_c2_cc9(s, v) __write_32bit_c2_register($25, s, v) 171#define nlm_write_c2_cc10(s, v) __write_32bit_c2_register($26, s, v) 172#define nlm_write_c2_cc11(s, v) __write_32bit_c2_register($27, s, v) 173#define nlm_write_c2_cc12(s, v) __write_32bit_c2_register($28, s, v) 174#define nlm_write_c2_cc13(s, v) __write_32bit_c2_register($29, s, v) 175#define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v) 176#define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v) 177 178#define nlm_read_c2_status0() __read_32bit_c2_register($2, 0) 179#define nlm_write_c2_status0(v) __write_32bit_c2_register($2, 0, v) 180#define nlm_read_c2_status1() __read_32bit_c2_register($2, 1) 181#define nlm_write_c2_status1(v) __write_32bit_c2_register($2, 1, v) 182#define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0) 183#define nlm_read_c2_config() __read_32bit_c2_register($3, 0) 184#define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v) 185#define nlm_read_c2_bucksize(b) __read_32bit_c2_register($4, b) 186#define nlm_write_c2_bucksize(b, v) __write_32bit_c2_register($4, b, v) 187 188#define nlm_read_c2_rx_msg0() __read_64bit_c2_register($1, 0) 189#define nlm_read_c2_rx_msg1() __read_64bit_c2_register($1, 1) 190#define nlm_read_c2_rx_msg2() __read_64bit_c2_register($1, 2) 191#define nlm_read_c2_rx_msg3() __read_64bit_c2_register($1, 3) 192 193#define nlm_write_c2_tx_msg0(v) __write_64bit_c2_register($0, 0, v) 194#define nlm_write_c2_tx_msg1(v) __write_64bit_c2_register($0, 1, v) 195#define nlm_write_c2_tx_msg2(v) __write_64bit_c2_register($0, 2, v) 196#define nlm_write_c2_tx_msg3(v) __write_64bit_c2_register($0, 3, v) 197 198#define FMN_STN_RX_QSIZE 256 199#define FMN_NSTATIONS 128 200#define FMN_CORE_NBUCKETS 8 201 202static inline void nlm_msgsnd(unsigned int stid) 203{ 204 __asm__ volatile ( 205 ".set push\n" 206 ".set noreorder\n" 207 ".set noat\n" 208 "move $1, %0\n" 209 "c2 0x10001\n" /* msgsnd $1 */ 210 ".set pop\n" 211 : : "r" (stid) : "$1" 212 ); 213} 214 215static inline void nlm_msgld(unsigned int pri) 216{ 217 __asm__ volatile ( 218 ".set push\n" 219 ".set noreorder\n" 220 ".set noat\n" 221 "move $1, %0\n" 222 "c2 0x10002\n" /* msgld $1 */ 223 ".set pop\n" 224 : : "r" (pri) : "$1" 225 ); 226} 227 228static inline void nlm_msgwait(unsigned int mask) 229{ 230 __asm__ volatile ( 231 ".set push\n" 232 ".set noreorder\n" 233 ".set noat\n" 234 "move $8, %0\n" 235 "c2 0x10003\n" /* msgwait $1 */ 236 ".set pop\n" 237 : : "r" (mask) : "$1" 238 ); 239} 240 241/* 242 * Disable interrupts and enable COP2 access 243 */ 244static inline uint32_t nlm_cop2_enable_irqsave(void) 245{ 246 uint32_t sr = read_c0_status(); 247 248 write_c0_status((sr & ~ST0_IE) | ST0_CU2); 249 return sr; 250} 251 252static inline void nlm_cop2_disable_irqrestore(uint32_t sr) 253{ 254 write_c0_status(sr); 255} 256 257static inline void nlm_fmn_setup_intr(int irq, unsigned int tmask) 258{ 259 uint32_t config; 260 261 config = (1 << 24) /* interrupt water mark - 1 msg */ 262 | (irq << 16) /* irq */ 263 | (tmask << 8) /* thread mask */ 264 | 0x2; /* enable watermark intr, disable empty intr */ 265 nlm_write_c2_config(config); 266} 267 268struct nlm_fmn_msg { 269 uint64_t msg0; 270 uint64_t msg1; 271 uint64_t msg2; 272 uint64_t msg3; 273}; 274 275static inline int nlm_fmn_send(unsigned int size, unsigned int code, 276 unsigned int stid, struct nlm_fmn_msg *msg) 277{ 278 unsigned int dest; 279 uint32_t status; 280 int i; 281 282 /* 283 * Make sure that all the writes pending at the cpu are flushed. 284 * Any writes pending on CPU will not be see by devices. L1/L2 285 * caches are coherent with IO, so no cache flush needed. 286 */ 287 __asm __volatile("sync"); 288 289 /* Load TX message buffers */ 290 nlm_write_c2_tx_msg0(msg->msg0); 291 nlm_write_c2_tx_msg1(msg->msg1); 292 nlm_write_c2_tx_msg2(msg->msg2); 293 nlm_write_c2_tx_msg3(msg->msg3); 294 dest = ((size - 1) << 16) | (code << 8) | stid; 295 296 /* 297 * Retry a few times on credit fail, this should be a 298 * transient condition, unless there is a configuration 299 * failure, or the receiver is stuck. 300 */ 301 for (i = 0; i < 8; i++) { 302 nlm_msgsnd(dest); 303 status = nlm_read_c2_status0(); 304 if ((status & 0x2) == 1) 305 pr_info("Send pending fail!\n"); 306 if ((status & 0x4) == 0) 307 return 0; 308 } 309 310 /* If there is a credit failure, return error */ 311 return status & 0x06; 312} 313 314static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid, 315 struct nlm_fmn_msg *msg) 316{ 317 uint32_t status, tmp; 318 319 nlm_msgld(bucket); 320 321 /* wait for load pending to clear */ 322 do { 323 status = nlm_read_c2_status0(); 324 } while ((status & 0x08) != 0); 325 326 /* receive error bits */ 327 tmp = status & 0x30; 328 if (tmp != 0) 329 return tmp; 330 331 *size = ((status & 0xc0) >> 6) + 1; 332 *code = (status & 0xff00) >> 8; 333 *stid = (status & 0x7f0000) >> 16; 334 msg->msg0 = nlm_read_c2_rx_msg0(); 335 msg->msg1 = nlm_read_c2_rx_msg1(); 336 msg->msg2 = nlm_read_c2_rx_msg2(); 337 msg->msg3 = nlm_read_c2_rx_msg3(); 338 339 return 0; 340} 341 342struct xlr_fmn_info { 343 int num_buckets; 344 int start_stn_id; 345 int end_stn_id; 346 int credit_config[128]; 347}; 348 349struct xlr_board_fmn_config { 350 int bucket_size[128]; /* size of buckets for all stations */ 351 struct xlr_fmn_info cpu[8]; 352 struct xlr_fmn_info gmac[2]; 353 struct xlr_fmn_info dma; 354 struct xlr_fmn_info cmp; 355 struct xlr_fmn_info sae; 356 struct xlr_fmn_info xgmac[2]; 357}; 358 359extern int nlm_register_fmn_handler(int start, int end, 360 void (*fn)(int, int, int, int, struct nlm_fmn_msg *, void *), 361 void *arg); 362extern void xlr_percpu_fmn_init(void); 363extern void nlm_setup_fmn_irq(void); 364extern void xlr_board_info_setup(void); 365 366extern struct xlr_board_fmn_config xlr_board_fmn_config; 367#endif 368