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