Home | History | Annotate | Line # | Download | only in cavium
      1 /*	$NetBSD: octeonvar.h,v 1.18 2022/01/26 11:48:54 andvar Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef _MIPS_OCTEON_OCTEONVAR_H_
     33 #define _MIPS_OCTEON_OCTEONVAR_H_
     34 
     35 #include <sys/bus.h>
     36 #include <sys/evcnt.h>
     37 #include <sys/kcpuset.h>
     38 #include <mips/locore.h>
     39 #include <dev/pci/pcivar.h>
     40 
     41 #include <mips/cavium/octeonreg.h>
     42 #include <mips/cache_octeon.h>
     43 
     44 /* XXX elsewhere */
     45 #define	_ASM_PROLOGUE \
     46 		"	.set push			\n" \
     47 		"	.set noreorder			\n"
     48 #define	_ASM_PROLOGUE_MIPS64 \
     49 		_ASM_PROLOGUE				\
     50 		"	.set mips64			\n"
     51 #define	_ASM_PROLOGUE_OCTEON \
     52 		_ASM_PROLOGUE				\
     53 		"	.set arch=octeon		\n"
     54 #define	_ASM_EPILOGUE \
     55 		"	.set pop			\n"
     56 
     57 #ifdef _KERNEL
     58 extern int	octeon_core_ver;
     59 #endif /* _KERNEL */
     60 #define	OCTEON_1		1
     61 #define	OCTEON_PLUS		10	/* arbitrary, keep sequence for others */
     62 #define	OCTEON_2		2
     63 #define	OCTEON_3		3
     64 
     65 struct octeon_config {
     66 	struct mips_bus_space mc_iobus_bust;
     67 	struct mips_bus_space mc_bootbus_bust;
     68 	struct mips_pci_chipset mc_pc;
     69 
     70 	struct mips_bus_dma_tag mc_iobus_dmat;
     71 	struct mips_bus_dma_tag mc_bootbus_dmat;
     72 	struct mips_bus_dma_tag mc_core1_dmat;
     73 	struct mips_bus_dma_tag mc_fpa_dmat;
     74 
     75 	struct extent *mc_io_ex;
     76 	struct extent *mc_mem_ex;
     77 
     78 	int	mc_mallocsafe;
     79 };
     80 
     81 #define NIRQS	128
     82 #define NBANKS	2
     83 
     84 struct cpu_softc {
     85 	struct cpu_info *cpu_ci;
     86 
     87 	uint64_t cpu_ip2_sum0;
     88 	uint64_t cpu_ip3_sum0;
     89 	uint64_t cpu_ip4_sum0;
     90 
     91 	uint64_t cpu_int_sum1;
     92 
     93 	uint64_t cpu_ip2_en[NBANKS];
     94 	uint64_t cpu_ip3_en[NBANKS];
     95 	uint64_t cpu_ip4_en[NBANKS];
     96 
     97 	uint64_t cpu_ip2_enable[NBANKS];
     98 	uint64_t cpu_ip3_enable[NBANKS];
     99 	uint64_t cpu_ip4_enable[NBANKS];
    100 
    101 	struct evcnt cpu_intr_evs[NIRQS];
    102 
    103 	void *cpu_wdog_sih;		// wdog softint handler
    104 	uint64_t cpu_wdog;
    105 	uint64_t cpu_pp_poke;
    106 
    107 #ifdef MULTIPROCESSOR
    108 	uint64_t cpu_mbox_set;
    109 	uint64_t cpu_mbox_clr;
    110 #endif
    111 } __aligned(OCTEON_CACHELINE_SIZE);
    112 
    113 /*
    114  * FPA map
    115  */
    116 
    117 #define	OCTEON_POOL_NO_PKT	0
    118 #define	OCTEON_POOL_NO_WQE	1
    119 #define	OCTEON_POOL_NO_CMD	2
    120 #define	OCTEON_POOL_NO_SG	3
    121 #define	OCTEON_POOL_NO_XXX_4	4
    122 #define	OCTEON_POOL_NO_XXX_5	5
    123 #define	OCTEON_POOL_NO_XXX_6	6
    124 #define	OCTEON_POOL_NO_DUMP	7	/* FPA debug dump */
    125 
    126 #define	OCTEON_POOL_SIZE_PKT	2048	/* 128 x 16 */
    127 #define	OCTEON_POOL_SIZE_WQE	128	/* 128 x 1 */
    128 #define	OCTEON_POOL_SIZE_CMD	1024	/* 128 x 8 */
    129 #define	OCTEON_POOL_SIZE_SG	512	/* 128 x 4 */
    130 #define	OCTEON_POOL_SIZE_XXX_4	0
    131 #define	OCTEON_POOL_SIZE_XXX_5	0
    132 #define	OCTEON_POOL_SIZE_XXX_6	0
    133 #define	OCTEON_POOL_SIZE_XXX_7	0
    134 
    135 #define	OCTEON_POOL_NELEMS_PKT		4096
    136 #define	OCTEON_POOL_NELEMS_WQE		4096
    137 #define	OCTEON_POOL_NELEMS_CMD		32
    138 #define	OCTEON_POOL_NELEMS_SG		1024
    139 #define	OCTEON_POOL_NELEMS_XXX_4	0
    140 #define	OCTEON_POOL_NELEMS_XXX_5	0
    141 #define	OCTEON_POOL_NELEMS_XXX_6	0
    142 #define	OCTEON_POOL_NELEMS_XXX_7	0
    143 
    144 /*
    145  * CVMSEG (``scratch'') memory map
    146  */
    147 
    148 #define CVMSEG_LM_RNM_SIZE	16	/* limited by CN70XX hardware (why?) */
    149 #define CVMSEG_LM_ETHER_COUNT	4	/* limits number of cnmac devices */
    150 
    151 struct octeon_cvmseg_map {
    152 	uint64_t		csm_pow_intr;
    153 
    154 	struct octeon_cvmseg_ether_map {
    155 		uint64_t	csm_ether_fau_done;
    156 	} csm_ether[CVMSEG_LM_ETHER_COUNT];
    157 
    158 	uint64_t	csm_rnm[CVMSEG_LM_RNM_SIZE];
    159 } __packed;
    160 #define	OCTEON_CVMSEG_OFFSET(entry) \
    161 	offsetof(struct octeon_cvmseg_map, entry)
    162 #define	OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
    163 	(offsetof(struct octeon_cvmseg_map, csm_ether) + \
    164 	 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
    165 	 offsetof(struct octeon_cvmseg_ether_map, entry))
    166 
    167 /*
    168  * FAU register map
    169  *
    170  * => FAU registers exist in FAU unit
    171  * => devices (PKO) can access these registers
    172  * => CPU can read those values after loading them into CVMSEG
    173  */
    174 struct octfau_map {
    175 	struct {
    176 		/* PKO command index */
    177 		uint64_t	_fau_map_port_pkocmdidx;
    178 		/* send requested */
    179 		uint64_t	_fau_map_port_txreq;
    180 		/* send completed */
    181 		uint64_t	_fau_map_port_txdone;
    182 		/* XXX */
    183 		uint64_t	_fau_map_port_pad;
    184 	} __packed _fau_map_port[3];
    185 };
    186 
    187 /*
    188  * POW qos/group map
    189  */
    190 
    191 #define	OCTEON_POW_QOS_PIP		0
    192 #define	OCTEON_POW_QOS_CORE1		1
    193 #define	OCTEON_POW_QOS_XXX_2		2
    194 #define	OCTEON_POW_QOS_XXX_3		3
    195 #define	OCTEON_POW_QOS_XXX_4		4
    196 #define	OCTEON_POW_QOS_XXX_5		5
    197 #define	OCTEON_POW_QOS_XXX_6		6
    198 #define	OCTEON_POW_QOS_XXX_7		7
    199 
    200 #define	OCTEON_POW_GROUP_MAX		16
    201 
    202 #ifdef _KERNEL
    203 extern struct octeon_config	octeon_configuration;
    204 
    205 const char	*octeon_cpu_model(mips_prid_t);
    206 
    207 void		octeon_bus_io_init(bus_space_tag_t, void *);
    208 void		octeon_bus_mem_init(bus_space_tag_t, void *);
    209 void		octeon_cal_timer(int);
    210 void		octeon_dma_init(struct octeon_config *);
    211 void		octeon_intr_init(struct cpu_info *);
    212 void		octeon_iointr(int, vaddr_t, uint32_t);
    213 void		octpci_init(pci_chipset_tag_t, struct octeon_config *);
    214 void		*octeon_intr_establish(int, int, int (*)(void *), void *);
    215 void		octeon_intr_disestablish(void *cookie);
    216 
    217 int		octeon_ioclock_speed(void);
    218 void		octeon_soft_reset(void);
    219 
    220 void		octeon_reset_vector(void);
    221 uint64_t	mips_cp0_cvmctl_read(void);
    222 void		mips_cp0_cvmctl_write(uint64_t);
    223 #endif /* _KERNEL */
    224 
    225 #if defined(__mips_n32)
    226 #define ffs64	__builtin_ffsll
    227 #elif defined(_LP64)
    228 #define ffs64	__builtin_ffsl
    229 #else
    230 #error unknown ABI
    231 #endif
    232 
    233 /*
    234  * Prefetch
    235  *
    236  *	OCTEON_PREF		normal (L1 and L2)
    237  *	OCTEON_PREF_L1		L1 only
    238  *	OCTEON_PREF_L2		L2 only
    239  *	OCTEON_PREF_DWB		don't write back
    240  *	OCTEON_PREF_PFS		prepare for store
    241  */
    242 #define __OCTEON_PREF_N(n, base, offset)			\
    243 	__asm __volatile (					\
    244 		"	.set	push				\
    245 		"	.set	arch=octeon			\n" \
    246 		"	pref	"#n", "#offset"(%[base])	\n" \
    247 		"	.set	pop				\
    248 		: : [base] "d" (base)				\
    249 	)
    250 #define __OCTEON_PREF_0(base, offset)	__OCTEON_PREF_N(0, base, offset)
    251 #define __OCTEON_PREF_4(base, offset)	__OCTEON_PREF_N(4, base, offset)
    252 #define __OCTEON_PREF_28(base, offset)	__OCTEON_PREF_N(28, base, offset)
    253 #define __OCTEON_PREF_29(base, offset)	__OCTEON_PREF_N(29, base, offset)
    254 #define __OCTEON_PREF_30(base, offset)	__OCTEON_PREF_N(30, base, offset)
    255 #define OCTEON_PREF(base, offset)	__OCTEON_PREF_0(base, offset)
    256 #define OCTEON_PREF_L1(base, offset)	__OCTEON_PREF_4(base, offset)
    257 #define OCTEON_PREF_L2(base, offset)	__OCTEON_PREF_28(base, offset)
    258 #define OCTEON_PREF_DWB(base, offset)	__OCTEON_PREF_29(base, offset)
    259 #define OCTEON_PREF_PFS(base, offset)	__OCTEON_PREF_30(base, offset)
    260 
    261 /*
    262  * Sync
    263  */
    264 #define OCTEON_SYNCCOMMON(name) \
    265 	__asm __volatile ( \
    266 		_ASM_PROLOGUE_OCTEON			\
    267 		"	"#name"				\n" \
    268 		_ASM_EPILOGUE				\
    269 		::: "memory")
    270 #define OCTEON_SYNCIOBDMA	OCTEON_SYNCCOMMON(synciobdma)
    271 #define OCTEON_SYNCW		OCTEON_SYNCCOMMON(syncw)
    272 #define OCTEON_SYNC		OCTEON_SYNCCOMMON(sync)
    273 #define OCTEON_SYNCWS		OCTEON_SYNCCOMMON(syncws)
    274 #define OCTEON_SYNCS		OCTEON_SYNCCOMMON(syncs)
    275 
    276 /* octeon core does not use cca to determine cacheability */
    277 #define OCTEON_CCA_NONE UINT64_C(0)
    278 
    279 static __inline uint64_t
    280 octeon_xkphys_read_8(paddr_t address)
    281 {
    282 	return mips3_ld(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address));
    283 }
    284 
    285 static __inline void
    286 octeon_xkphys_write_8(paddr_t address, uint64_t value)
    287 {
    288 	mips3_sd(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address), value);
    289 }
    290 
    291 static __inline void
    292 octeon_iobdma_write_8(uint64_t value)
    293 {
    294 
    295 	octeon_xkphys_write_8(OCTEON_IOBDMA_ADDR, value);
    296 }
    297 
    298 static __inline uint64_t
    299 octeon_cvmseg_read_8(size_t offset)
    300 {
    301 
    302 	return octeon_xkphys_read_8(OCTEON_CVMSEG_LM + offset);
    303 }
    304 
    305 static __inline void
    306 octeon_cvmseg_write_8(size_t offset, uint64_t value)
    307 {
    308 
    309 	octeon_xkphys_write_8(OCTEON_CVMSEG_LM + offset, value);
    310 }
    311 
    312 #endif	/* _MIPS_OCTEON_OCTEONVAR_H_ */
    313