Home | History | Annotate | Line # | Download | only in dev
      1 /*	$NetBSD: octeon_fau.c,v 1.4 2020/06/23 05:14:18 simonb 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.4 2020/06/23 05:14:18 simonb 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	octfau_op_load(uint64_t);
     40 static inline void	octfau_op_iobdma(int, uint64_t);
     41 static inline void	octfau_op_store(uint64_t, int64_t);
     42 static inline int64_t	octfau_op_load_paddr(int, int, int);
     43 static inline void	octfau_op_iobdma_store_data(int, int, int, int, int);
     44 static inline void	octfau_op_store_paddr(int, int, int64_t);
     45 
     46 
     47 /* ---- utilities */
     48 
     49 static inline int64_t
     50 octfau_op_load(uint64_t args)
     51 {
     52 	paddr_t addr = OCTEON_ADDR_IO_DID(FAU_MAJOR_DID, FAU_SUB_DID) |
     53 	    __SHIFTIN(args, OCTEON_ADDR_OFFSET);
     54 
     55 	return octeon_xkphys_read_8(addr);
     56 }
     57 
     58 static inline void
     59 octfau_op_store(uint64_t args, int64_t value)
     60 {
     61 	paddr_t addr = OCTEON_ADDR_IO_DID(FAU_MAJOR_DID, FAU_SUB_DID) |
     62 	    __SHIFTIN(args, OCTEON_ADDR_OFFSET);
     63 
     64 	octeon_xkphys_write_8(addr, value);
     65 }
     66 
     67 /* ---- operation primitives */
     68 
     69 /*
     70  * Fetch-and-Add Operations
     71  */
     72 
     73 /* Load Operations */
     74 
     75 /* Load Physical Address for FAU Operations */
     76 
     77 static inline int64_t
     78 octfau_op_load_paddr(int incval, int tagwait, int reg)
     79 {
     80 	uint64_t args =
     81 	    __SHIFTIN(incval, POW_LOAD_INCVAL) |
     82 	    __SHIFTIN(tagwait, POW_LOAD_TAGWAIT) |
     83 	    __SHIFTIN(reg, POW_LOAD_REG);
     84 
     85 	return octfau_op_load(args);
     86 }
     87 
     88 /* Store Operations */
     89 
     90 /* Store Physical Address for FAU Operations */
     91 
     92 static inline void
     93 octfau_op_store_paddr(int noadd, int reg, int64_t value)
     94 {
     95 	uint64_t args = POW_STORE_NOADD | __SHIFTIN(reg, POW_STORE_REG);
     96 
     97 	octfau_op_store(args, value);
     98 }
     99 
    100 /* ---- API */
    101 
    102 void
    103 octfau_op_init(struct octfau_desc *fd, size_t scroff, size_t regno)
    104 {
    105 
    106 	fd->fd_scroff = scroff;
    107 	fd->fd_regno = regno;
    108 }
    109 
    110 uint64_t
    111 octfau_op_save(struct octfau_desc *fd)
    112 {
    113 
    114 	OCTEON_SYNCIOBDMA/* XXX */;
    115 	return octeon_cvmseg_read_8(fd->fd_scroff);
    116 }
    117 
    118 void
    119 octfau_op_restore(struct octfau_desc *fd, uint64_t backup)
    120 {
    121 
    122 	octeon_cvmseg_write_8(fd->fd_scroff, backup);
    123 }
    124 
    125 int64_t
    126 octfau_op_inc_8(struct octfau_desc *fd, int64_t v)
    127 {
    128 
    129 	octfau_op_iobdma_store_data(fd->fd_scroff, v, 0, OCT_FAU_OP_SIZE_64/* XXX */,
    130 	    fd->fd_regno);
    131 	OCTEON_SYNCIOBDMA/* XXX */;
    132 	return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
    133 }
    134 
    135 int64_t
    136 octfau_op_incwait_8(struct octfau_desc *fd, int v)
    137 {
    138 
    139 	octfau_op_iobdma_store_data(fd->fd_scroff, v, 1, OCT_FAU_OP_SIZE_64/* XXX */,
    140 	    fd->fd_regno);
    141 	/* XXX */
    142 	OCTEON_SYNCIOBDMA/* XXX */;
    143 	/* XXX */
    144 	return octeon_cvmseg_read_8(fd->fd_scroff)/* XXX */;
    145 }
    146 
    147 void
    148 octfau_op_add_8(struct octfau_desc *fd, int64_t v)
    149 {
    150 
    151 	octfau_op_store_paddr(0, fd->fd_regno, v);
    152 }
    153 
    154 void
    155 octfau_op_set_8(struct octfau_desc *fd, int64_t v)
    156 {
    157 
    158 	octfau_op_store_paddr(1, fd->fd_regno, v);
    159 }
    160