1 /* $OpenBSD: octeonvar.h,v 1.49 2020/09/04 15:18:05 visa Exp $ */ 2 /* $NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $ */ 3 4 /*- 5 * Copyright (c) 2001 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe. 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 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef _MIPS_OCTEON_OCTEONVAR_H_ 34 #define _MIPS_OCTEON_OCTEONVAR_H_ 35 36 #include <machine/bus.h> 37 38 /* XXX elsewhere */ 39 #define _ASM_PROLOGUE \ 40 " .set push \n" \ 41 " .set noreorder \n" 42 #define _ASM_PROLOGUE_MIPS64 \ 43 _ASM_PROLOGUE \ 44 " .set mips64 \n" 45 #define _ASM_PROLOGUE_OCTEON \ 46 _ASM_PROLOGUE \ 47 " .set arch=octeon \n" 48 #define _ASM_EPILOGUE \ 49 " .set pop \n" 50 /* 51 * subbits = __BITS64_GET(XXX, bits); 52 * bits = __BITS64_SET(XXX, subbits); 53 */ 54 #ifndef __BITS64_GET 55 #define __BITS64_GET(name, bits) \ 56 (((uint64_t)(bits) & name) >> name##_SHIFT) 57 #endif 58 #ifndef __BITS64_SET 59 #define __BITS64_SET(name, subbits) \ 60 (((uint64_t)(subbits) << name##_SHIFT) & name) 61 #endif 62 63 struct octeon_config { 64 bus_space_tag_t mc_iobus_bust; 65 bus_space_tag_t mc_bootbus_bust; 66 67 bus_dma_tag_t mc_iobus_dmat; 68 bus_dma_tag_t mc_bootbus_dmat; 69 }; 70 71 #define GPIO_CONFIG_MD_OUTPUT_SEL_MASK (GPIO_CONFIG_MD0 | GPIO_CONFIG_MD1) 72 #define GPIO_CONFIG_MD_USB0_VBUS_CTRL GPIO_CONFIG_MD0 73 #define GPIO_CONFIG_MD_USB1_VBUS_CTRL GPIO_CONFIG_MD1 74 75 /* 76 * FPA map 77 */ 78 79 #define OCTEON_POOL_NO_PKT 0 80 #define OCTEON_POOL_NO_WQE 1 81 #define OCTEON_POOL_NO_CMD 2 82 #define OCTEON_POOL_NO_SG 3 83 #define OCTEON_POOL_NO_XXX_4 4 84 #define OCTEON_POOL_NO_XXX_5 5 85 #define OCTEON_POOL_NO_XXX_6 6 86 #define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */ 87 88 #define OCTEON_POOL_SIZE_PKT 1920 /* 128 x 15 */ 89 #define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */ 90 #define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */ 91 #define OCTEON_POOL_SIZE_SG 128 /* 128 x 1 */ 92 #define OCTEON_POOL_SIZE_XXX_4 0 93 #define OCTEON_POOL_SIZE_XXX_5 0 94 #define OCTEON_POOL_SIZE_XXX_6 0 95 #define OCTEON_POOL_SIZE_XXX_7 0 96 97 #define OCTEON_POOL_NELEMS_PKT 4096 98 #define OCTEON_POOL_NELEMS_WQE 4096 99 #define OCTEON_POOL_NELEMS_CMD 32 100 #define OCTEON_POOL_NELEMS_SG 4096 101 #define OCTEON_POOL_NELEMS_XXX_4 0 102 #define OCTEON_POOL_NELEMS_XXX_5 0 103 #define OCTEON_POOL_NELEMS_XXX_6 0 104 #define OCTEON_POOL_NELEMS_XXX_7 0 105 106 /* 107 * CVMSEG (``scratch'') memory map 108 */ 109 struct octeon_cvmseg_map { 110 uint64_t csm_pow_intr; 111 112 struct octeon_cvmseg_ether_map { 113 uint64_t csm_ether_fau_done; 114 } csm_ether[12/* XXX */]; 115 } __packed; 116 #define OCTEON_CVMSEG_OFFSET(entry) \ 117 offsetof(struct octeon_cvmseg_map, entry) 118 #define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \ 119 (offsetof(struct octeon_cvmseg_map, csm_ether) + \ 120 sizeof(struct octeon_cvmseg_ether_map) * (n) + \ 121 offsetof(struct octeon_cvmseg_ether_map, entry)) 122 123 /* 124 * FAU register map 125 * 126 * => FAU registers exist in FAU unit 127 * => devices (PKO) can access these registers 128 * => CPU can read those values after loading them into CVMSEG 129 */ 130 struct octeon_fau_map { 131 struct { 132 /* PKO command index */ 133 uint64_t _fau_map_port_pkocmdidx; 134 /* send requested */ 135 uint64_t _fau_map_port_txreq; 136 /* send completed */ 137 uint64_t _fau_map_port_txdone; 138 /* XXX */ 139 uint64_t _fau_map_port_pad; 140 } __packed _fau_map_port[3]; 141 }; 142 143 /* 144 * POW qos/group map 145 */ 146 147 #define OCTEON_POW_QOS_PIP 0 148 #define OCTEON_POW_QOS_CORE1 1 149 #define OCTEON_POW_QOS_XXX_2 2 150 #define OCTEON_POW_QOS_XXX_3 3 151 #define OCTEON_POW_QOS_XXX_4 4 152 #define OCTEON_POW_QOS_XXX_5 5 153 #define OCTEON_POW_QOS_XXX_6 6 154 #define OCTEON_POW_QOS_XXX_7 7 155 156 #define OCTEON_POW_GROUP_MAX 16 157 158 enum cnmac_stat { 159 cnmac_stat_rx_toto_gmx, 160 cnmac_stat_rx_totp_gmx, 161 cnmac_stat_rx_toto_pip, 162 cnmac_stat_rx_totp_pip, 163 cnmac_stat_rx_h64, 164 cnmac_stat_rx_h127, 165 cnmac_stat_rx_h255, 166 cnmac_stat_rx_h511, 167 cnmac_stat_rx_h1023, 168 cnmac_stat_rx_h1518, 169 cnmac_stat_rx_hmax, 170 cnmac_stat_rx_bcast, 171 cnmac_stat_rx_mcast, 172 cnmac_stat_rx_qdpo, 173 cnmac_stat_rx_qdpp, 174 cnmac_stat_rx_fcs, 175 cnmac_stat_rx_frag, 176 cnmac_stat_rx_undersz, 177 cnmac_stat_rx_jabber, 178 cnmac_stat_rx_oversz, 179 cnmac_stat_rx_raw, 180 cnmac_stat_rx_bad, 181 cnmac_stat_rx_drop, 182 cnmac_stat_rx_ctl, 183 cnmac_stat_rx_dmac, 184 cnmac_stat_tx_toto, 185 cnmac_stat_tx_totp, 186 cnmac_stat_tx_hmin, 187 cnmac_stat_tx_h64, 188 cnmac_stat_tx_h127, 189 cnmac_stat_tx_h255, 190 cnmac_stat_tx_h511, 191 cnmac_stat_tx_h1023, 192 cnmac_stat_tx_h1518, 193 cnmac_stat_tx_hmax, 194 cnmac_stat_tx_bcast, 195 cnmac_stat_tx_mcast, 196 cnmac_stat_tx_coll, 197 cnmac_stat_tx_defer, 198 cnmac_stat_tx_scol, 199 cnmac_stat_tx_mcol, 200 cnmac_stat_tx_ctl, 201 cnmac_stat_tx_uflow, 202 cnmac_stat_count 203 }; 204 205 /* 206 * Octeon board types known to work with OpenBSD/octeon. 207 * NB: BOARD_TYPE_UBIQUITI_E100 is also used by other vendors, but we don't run 208 * on those boards yet. 209 */ 210 #define BOARD_TYPE_CN3010_EVB_HS5 11 211 #define BOARD_TYPE_UBIQUITI_E100 20002 212 #define BOARD_TYPE_UBIQUITI_E200 20003 213 #define BOARD_TYPE_UBIQUITI_E120 20004 214 #define BOARD_TYPE_UBIQUITI_E220 20005 215 #define BOARD_TYPE_UBIQUITI_E1000 20010 216 #define BOARD_TYPE_RHINOLABS_SHASTA 20012 217 #define BOARD_TYPE_DSR_500 20015 218 #define BOARD_TYPE_UBIQUITI_E300 20300 219 220 #if defined(_KERNEL) || defined(_STANDALONE) 221 #define OCTEON_ARGV_MAX 64 222 223 struct boot_desc { 224 uint32_t desc_ver; 225 uint32_t desc_size; 226 uint64_t stack_top; 227 uint64_t heap_start; 228 uint64_t heap_end; 229 uint64_t __unused17; 230 uint64_t __unused16; 231 uint32_t __unused18; 232 uint32_t __unused15; 233 uint32_t __unused14; 234 uint32_t argc; 235 uint32_t argv[OCTEON_ARGV_MAX]; 236 uint32_t flags; 237 uint32_t core_mask; 238 uint32_t dram_size; 239 uint32_t phy_mem_desc_addr; 240 uint32_t debugger_flag_addr; 241 uint32_t eclock; 242 uint32_t __unused10; 243 uint32_t __unused9; 244 uint16_t __unused8; 245 uint8_t __unused7; 246 uint8_t __unused6; 247 uint16_t __unused5; 248 uint8_t __unused4; 249 uint8_t __unused3; 250 uint8_t __unused2[20]; 251 uint8_t __unused1[6]; 252 uint8_t __unused0; 253 uint64_t boot_info_addr; 254 }; 255 256 struct boot_info { 257 uint32_t ver_major; 258 uint32_t ver_minor; 259 uint64_t stack_top; 260 uint64_t heap_start; 261 uint64_t heap_end; 262 uint64_t boot_desc_addr; 263 uint32_t exception_base_addr; 264 uint32_t stack_size; 265 uint32_t flags; 266 uint32_t core_mask; 267 uint32_t dram_size; 268 uint32_t phys_mem_desc_addr; 269 uint32_t debugger_flags_addr; 270 uint32_t eclock; 271 uint32_t dclock; 272 uint32_t __unused0; 273 uint16_t board_type; 274 uint8_t board_rev_major; 275 uint8_t board_rev_minor; 276 uint16_t __unused1; 277 uint8_t __unused2; 278 uint8_t __unused3; 279 char board_serial[20]; 280 uint8_t mac_addr_base[6]; 281 uint8_t mac_addr_count; 282 uint64_t cf_common_addr; 283 uint64_t cf_attr_addr; 284 uint64_t led_display_addr; 285 uint32_t dfaclock; 286 uint32_t config_flags; 287 /* The fields below are available when ver_minor >= 3. */ 288 uint64_t fdt_addr; 289 }; 290 291 struct octeon_bootmem_desc { 292 uint32_t lock; 293 uint32_t flags; 294 uint64_t head_addr; 295 uint32_t major_version; 296 uint32_t minor_version; 297 uint64_t app_data_addr; 298 uint64_t app_data_size; 299 uint32_t named_block_num_blocks; 300 uint32_t named_block_name_len; 301 uint64_t named_block_array_addr; 302 }; 303 304 struct octeon_bootmem_block { 305 uint64_t next; 306 uint64_t size; 307 }; 308 309 extern struct boot_desc *octeon_boot_desc; 310 extern struct boot_info *octeon_boot_info; 311 312 #ifdef _KERNEL 313 /* Device capabilities advertised in boot_info->config_flags */ 314 #define BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0) 315 #define BOOTINFO_CFG_FLAG_PCI_TARGET (1ull << 1) 316 #define BOOTINFO_CFG_FLAG_DEBUG (1ull << 2) 317 #define BOOTINFO_CFG_FLAG_NO_MAGIC (1ull << 3) 318 319 #define BOOTMEM_BLOCK_ALIGN 16 320 #define BOOTMEM_BLOCK_MASK (BOOTMEM_BLOCK_ALIGN - 1) 321 #define BOOTMEM_BLOCK_MIN_SIZE 16 322 323 int bootmem_alloc_region(paddr_t, size_t); 324 void bootmem_free(paddr_t, size_t); 325 326 int octeon_ioclock_speed(void); 327 328 #endif /* _KERNEL */ 329 #endif /* _KERNEL || _STANDALONE */ 330 331 static inline int 332 ffs64(uint64_t val) 333 { 334 int ret; 335 336 __asm volatile ( \ 337 _ASM_PROLOGUE_MIPS64 338 " dclz %0, %1 \n" 339 _ASM_EPILOGUE 340 : "=r"(ret) : "r"(val)); 341 return 64 - ret; 342 } 343 344 static inline int 345 ffs32(uint32_t val) 346 { 347 int ret; 348 349 __asm __volatile ( \ 350 _ASM_PROLOGUE_MIPS64 351 " clz %0, %1 \n" 352 _ASM_EPILOGUE 353 : "=r"(ret) : "r"(val)); 354 return 32 - ret; 355 } 356 357 static inline uint64_t 358 octeon_xkphys_read_8(paddr_t address) 359 { 360 volatile uint64_t *p = 361 (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)); 362 return (*p); 363 } 364 365 #define MIO_BOOT_BIST_STAT 0x00011800000000f8ULL 366 static inline void 367 octeon_xkphys_write_8(paddr_t address, uint64_t value) 368 { 369 *(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value; 370 371 /* 372 * It seems an immediate read is necessary when doing a write to an RSL 373 * register in order to complete the write. 374 * We use MIO_BOOT_BIST_STAT because it's apparently the fastest 375 * write. 376 */ 377 378 /* 379 * XXX 380 * This if would be better writen as: 381 * if ((address & 0xffffff0000000000ULL) == OCTEON_MIO_BOOT_BASE) { 382 * but octeonreg.h can't be included here and we want this inlined 383 * 384 * Note that the SDK masks with 0x7ffff but that doesn't make sense. 385 * This is a physical address. 386 */ 387 if (((address >> 40) & 0xfffff) == (0x118)) { 388 value = *(volatile uint64_t *) 389 (PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC)); 390 } 391 } 392 393 static inline void 394 octeon_iobdma_write_8(uint64_t value) 395 { 396 uint64_t addr = 0xffffffffffffa200ULL; 397 398 *(volatile uint64_t *)addr = value; 399 } 400 401 static inline void 402 octeon_lmtdma_write_8(off_t offset, uint64_t value) 403 { 404 *(volatile uint64_t *)(0xffffffffffffa400ULL + offset) = value; 405 } 406 407 static inline uint64_t 408 octeon_cvmseg_read_8(size_t offset) 409 { 410 return *(volatile uint64_t *)(0xffffffffffff8000ULL + offset); 411 } 412 413 static inline void 414 octeon_cvmseg_write_8(size_t offset, uint64_t value) 415 { 416 *(volatile uint64_t *)(0xffffffffffff8000ULL + offset) = value; 417 } 418 419 static inline uint32_t 420 octeon_get_coreid(void) 421 { 422 uint32_t coreid; 423 424 __asm volatile ( 425 _ASM_PROLOGUE_OCTEON 426 " rdhwr %0, $0\n" 427 _ASM_EPILOGUE 428 : "=r" (coreid)); 429 return coreid; 430 } 431 432 static inline uint64_t 433 octeon_get_cycles(void) 434 { 435 uint64_t tmp; 436 437 __asm volatile ( 438 _ASM_PROLOGUE_MIPS64 439 " dmfc0 %[tmp], $9, 6 \n" 440 _ASM_EPILOGUE 441 : [tmp]"=&r"(tmp)); 442 return tmp; 443 } 444 445 static inline uint64_t 446 octeon_get_cvmctl(void) 447 { 448 uint64_t tmp; 449 450 __asm volatile ( 451 _ASM_PROLOGUE_OCTEON 452 " dmfc0 %[tmp], $9, 7 \n" 453 _ASM_EPILOGUE 454 : [tmp]"=r"(tmp)); 455 return tmp; 456 } 457 458 static inline uint64_t 459 octeon_get_cvmmemctl(void) 460 { 461 uint64_t tmp; 462 463 __asm volatile ( 464 _ASM_PROLOGUE_OCTEON 465 " dmfc0 %[tmp], $11, 7 \n" 466 _ASM_EPILOGUE 467 : [tmp]"=r"(tmp)); 468 return tmp; 469 } 470 471 static inline void 472 octeon_set_cvmmemctl(uint64_t val) 473 { 474 __asm volatile ( 475 _ASM_PROLOGUE_OCTEON 476 " dmtc0 %[tmp], $11, 7 \n" 477 _ASM_EPILOGUE 478 : : [tmp]"r"(val) : "memory"); 479 } 480 481 static inline void 482 octeon_synciobdma(void) 483 { 484 __asm volatile ( 485 _ASM_PROLOGUE_OCTEON 486 " synciobdma\n" 487 _ASM_EPILOGUE 488 : : : "memory"); 489 } 490 491 #endif /* _MIPS_OCTEON_OCTEONVAR_H_ */ 492