1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2018 Marvell International Ltd. 4 */ 5 6#include <dm.h> 7#include <errno.h> 8#include <malloc.h> 9#include <misc.h> 10#include <net.h> 11#include <pci_ids.h> 12#include <linux/list.h> 13#include <asm/io.h> 14#include <asm/arch/board.h> 15#include <asm/arch/csrs/csrs-npa.h> 16 17#include "nix.h" 18 19struct udevice *rvu_af_dev; 20 21inline struct rvu_af *get_af(void) 22{ 23 return rvu_af_dev ? dev_get_priv(rvu_af_dev) : NULL; 24} 25 26void rvu_get_lfid_for_pf(int pf, int *nixid, int *npaid) 27{ 28 union nixx_af_rvu_lf_cfg_debug nix_lf_dbg; 29 union npa_af_rvu_lf_cfg_debug npa_lf_dbg; 30 union rvu_pf_func_s pf_func; 31 struct rvu_af *af = dev_get_priv(rvu_af_dev); 32 struct nix_af *nix_af = af->nix_af; 33 34 pf_func.u = 0; 35 pf_func.s.pf = pf; 36 37 nix_lf_dbg.u = 0; 38 nix_lf_dbg.s.pf_func = pf_func.u & 0xFFFF; 39 nix_lf_dbg.s.exec = 1; 40 nix_af_reg_write(nix_af, NIXX_AF_RVU_LF_CFG_DEBUG(), 41 nix_lf_dbg.u); 42 do { 43 nix_lf_dbg.u = nix_af_reg_read(nix_af, 44 NIXX_AF_RVU_LF_CFG_DEBUG()); 45 } while (nix_lf_dbg.s.exec); 46 47 if (nix_lf_dbg.s.lf_valid) 48 *nixid = nix_lf_dbg.s.lf; 49 50 debug("%s: nix lf_valid %d lf %d nixid %d\n", __func__, 51 nix_lf_dbg.s.lf_valid, nix_lf_dbg.s.lf, *nixid); 52 53 npa_lf_dbg.u = 0; 54 npa_lf_dbg.s.pf_func = pf_func.u & 0xFFFF; 55 npa_lf_dbg.s.exec = 1; 56 npa_af_reg_write(nix_af->npa_af, NPA_AF_RVU_LF_CFG_DEBUG(), 57 npa_lf_dbg.u); 58 do { 59 npa_lf_dbg.u = npa_af_reg_read(nix_af->npa_af, 60 NPA_AF_RVU_LF_CFG_DEBUG()); 61 } while (npa_lf_dbg.s.exec); 62 63 if (npa_lf_dbg.s.lf_valid) 64 *npaid = npa_lf_dbg.s.lf; 65 debug("%s: npa lf_valid %d lf %d npaid %d\n", __func__, 66 npa_lf_dbg.s.lf_valid, npa_lf_dbg.s.lf, *npaid); 67} 68 69struct nix_af *rvu_af_init(struct rvu_af *rvu_af) 70{ 71 struct nix_af *nix_af; 72 union rvu_af_addr_s block_addr; 73 int err; 74 75 nix_af = (struct nix_af *)calloc(1, sizeof(struct nix_af)); 76 if (!nix_af) { 77 printf("%s: out of memory\n", __func__); 78 goto error; 79 } 80 81 nix_af->dev = rvu_af->dev; 82 83 block_addr.u = 0; 84 block_addr.s.block = RVU_BLOCK_ADDR_E_NIXX(0); 85 nix_af->nix_af_base = rvu_af->af_base + block_addr.u; 86 87 nix_af->npa_af = (struct npa_af *)calloc(1, sizeof(struct npa_af)); 88 if (!nix_af->npa_af) { 89 printf("%s: out of memory\n", __func__); 90 goto error; 91 } 92 93 block_addr.u = 0; 94 block_addr.s.block = RVU_BLOCK_ADDR_E_NPA; 95 nix_af->npa_af->npa_af_base = rvu_af->af_base + block_addr.u; 96 97 block_addr.u = 0; 98 block_addr.s.block = RVU_BLOCK_ADDR_E_NPC; 99 nix_af->npc_af_base = rvu_af->af_base + block_addr.u; 100 101 debug("%s: Setting up npa admin\n", __func__); 102 err = npa_af_setup(nix_af->npa_af); 103 if (err) { 104 printf("%s: Error %d setting up NPA admin\n", __func__, err); 105 goto error; 106 } 107 debug("%s: Setting up nix af\n", __func__); 108 err = nix_af_setup(nix_af); 109 if (err) { 110 printf("%s: Error %d setting up NIX admin\n", __func__, err); 111 goto error; 112 } 113 debug("%s: nix_af: %p\n", __func__, nix_af); 114 return nix_af; 115 116error: 117 if (nix_af->npa_af) { 118 free(nix_af->npa_af); 119 memset(nix_af, 0, sizeof(*nix_af)); 120 } 121 if (nix_af) 122 free(nix_af); 123 return NULL; 124} 125 126int rvu_af_probe(struct udevice *dev) 127{ 128 struct rvu_af *af_ptr = dev_get_priv(dev); 129 130 af_ptr->af_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, 131 PCI_REGION_MEM); 132 debug("%s RVU AF BAR %p\n", __func__, af_ptr->af_base); 133 af_ptr->dev = dev; 134 rvu_af_dev = dev; 135 136 af_ptr->nix_af = rvu_af_init(af_ptr); 137 if (!af_ptr->nix_af) { 138 printf("%s: Error: could not initialize NIX AF\n", __func__); 139 return -1; 140 } 141 debug("%s: Done\n", __func__); 142 143 return 0; 144} 145 146int rvu_af_remove(struct udevice *dev) 147{ 148 struct rvu_af *rvu_af = dev_get_priv(dev); 149 150 nix_af_shutdown(rvu_af->nix_af); 151 npa_af_shutdown(rvu_af->nix_af->npa_af); 152 npc_af_shutdown(rvu_af->nix_af); 153 154 debug("%s: rvu af down --\n", __func__); 155 return 0; 156} 157 158U_BOOT_DRIVER(rvu_af) = { 159 .name = "rvu_af", 160 .id = UCLASS_MISC, 161 .probe = rvu_af_probe, 162 .remove = rvu_af_remove, 163 .priv_auto = sizeof(struct rvu_af), 164}; 165 166static struct pci_device_id rvu_af_supported[] = { 167 { PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_CAVIUM_RVU_AF) }, 168 {} 169}; 170 171U_BOOT_PCI_DEVICE(rvu_af, rvu_af_supported); 172