Home | History | Annotate | Line # | Download | only in dev
octeon_fau.c revision 1.1.18.2
      1 /*	$NetBSD: octeon_fau.c,v 1.1.18.2 2017/12/03 11:36:27 jdolecek Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2007 Internet Initiative Japan, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     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 the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: octeon_fau.c,v 1.1.18.2 2017/12/03 11:36:27 jdolecek Exp $");
     31 
     32 #include <sys/param.h>
     33 #include <sys/systm.h>
     34 #include <mips/locore.h>
     35 #include <mips/cavium/octeonvar.h>
     36 #include <mips/cavium/dev/octeon_faureg.h>
     37 #include <mips/cavium/dev/octeon_fauvar.h>
     38 
     39 static inline int64_t	octeon_fau_op_load(uint64_t);
     40 static inline void	octeon_fau_op_iobdma(int, uint64_t);
     41 static inline void	octeon_fau_op_store(uint64_t, int64_t);
     42 static inline int64_t	octeon_fau_op_load_paddr(int, int, int);
     43 static inline void	octeon_fau_op_iobdma_store_data(int, int, int, int, int);
     44 static inline void	octeon_fau_op_store_paddr(int, int, int64_t);
     45 
     46 
     47 /* ---- utilities */
     48 
     49 static inline int64_t
     50 octeon_fau_op_load(uint64_t args)
     51 {
     52 	paddr_t addr;
     53 
     54 	addr =
     55 	    ((uint64_t)1 << 48) |
     56 	    ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
     57 	    ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
     58 	    ((uint64_t)(args & 0xfffffffffULL) << 0);
     59 	return octeon_read_csr(addr);
     60 }
     61 
     62 static inline void
     63 octeon_fau_op_store(uint64_t args, int64_t value)
     64 {
     65 	paddr_t addr;
     66 
     67 	addr =
     68 	    ((uint64_t)1 << 48) |
     69 	    ((uint64_t)(CN30XXFAU_MAJORDID & 0x1f) << 43) |
     70 	    ((uint64_t)(CN30XXFAU_SUBDID & 0x7) << 40) |
     71 	    ((uint64_t)(args & 0xfffffffffULL) << 0);
     72 	octeon_write_csr(addr, value);
     73 }
     74 
     75 /* ---- operation primitives */
     76 
     77 /*
     78  * Fetch-and-Add Operations
     79  */
     80 
     81 /* Load Operations */
     82 
     83 /* Load Physical Address for FAU Operations */
     84 
     85 static inline int64_t
     86 octeon_fau_op_load_paddr(int incval, int tagwait, int reg)
     87 {
     88 	uint64_t args;
     89 
     90 	args =
     91 	    ((uint64_t)(incval & 0x3fffff) << 14) |
     92 	    ((uint64_t)(tagwait & 0x1) << 13) |
     93 	    ((uint64_t)(reg & 0x7ff) << 0);
     94 	return octeon_fau_op_load(args);
     95 }
     96 
     97 /* Store Operations */
     98 
     99 /* Store Physical Address for FAU Operations */
    100 
    101 static inline void
    102 octeon_fau_op_store_paddr(int noadd, int reg, int64_t value)
    103 {
    104 	uint64_t args;
    105 
    106 	args =
    107 	    ((uint64_t)(noadd & 0x1) << 13) |
    108 	    ((uint64_t)(reg & 0x7ff) << 0);
    109 	octeon_fau_op_store(args, value);
    110 }
    111 
    112 /* ---- API */
    113 
    114 void
    115 octeon_fau_op_init(struct octeon_fau_desc *fd, size_t scroff, size_t regno)
    116 {
    117 	fd->fd_scroff = scroff;
    118 	fd->fd_regno = regno;
    119 }
    120 
    121 uint64_t
    122 octeon_fau_op_save(struct octeon_fau_desc *fd)
    123 {
    124 	OCTEON_SYNCIOBDMA/* XXX */;
    125 	return octeon_cvmseg_read_8(fd->fd_scroff);
    126 }
    127 
    128 void
    129 octeon_fau_op_restore(struct octeon_fau_desc *fd, uint64_t backup)
    130 {
    131 	octeon_cvmseg_write_8(fd->fd_scroff, backup);
    132 }
    133 
    134 int64_t
    135 octeon_fau_op_inc_8(struct octeon_fau_desc *fd, int64_t v)
    136 {
    137 	octeon_fau_op_iobdma_store_data(fd->fd_scroff, v, 0, OCT_FAU_OP_SIZE_64/* XXX */,
    138 	    fd->fd_regno);
    139 	OCTEON_SYNCIOBDMA/* XXX */;
    140 	return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
    141 }
    142 
    143 int64_t
    144 octeon_fau_op_incwait_8(struct octeon_fau_desc *fd, int v)
    145 {
    146 	octeon_fau_op_iobdma_store_data(fd->fd_scroff, v, 1, OCT_FAU_OP_SIZE_64/* XXX */,
    147 	    fd->fd_regno);
    148 	/* XXX */
    149 	OCTEON_SYNCIOBDMA/* XXX */;
    150 	/* XXX */
    151 	return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
    152 }
    153 
    154 void
    155 octeon_fau_op_add_8(struct octeon_fau_desc *fd, int64_t v)
    156 {
    157 	octeon_fau_op_store_paddr(0, fd->fd_regno, v);
    158 }
    159 
    160 void
    161 octeon_fau_op_set_8(struct octeon_fau_desc *fd, int64_t v)
    162 {
    163 	octeon_fau_op_store_paddr(1, fd->fd_regno, v);
    164 }
    165