1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/cmn_err.h> 29 #include <sys/errno.h> 30 #include <sys/systm.h> 31 #include <sys/sunddi.h> 32 #include <sys/pci_cfgspace.h> 33 #include <sys/pci.h> 34 #include <sys/pcie.h> 35 #include <vm/seg_kmem.h> 36 #include <sys/mman.h> 37 #include <sys/cpu_module.h> 38 #include "nb5000.h" 39 40 static ddi_acc_handle_t dev_16_hdl[NB_PCI_NFUNC]; 41 static ddi_acc_handle_t dev_17_hdl[NB_PCI_NFUNC]; 42 static ddi_acc_handle_t dev_21_hdl; 43 static ddi_acc_handle_t dev_22_hdl; 44 static ddi_acc_handle_t dev_pci_hdl[NB_PCI_DEV]; 45 46 void 47 nb_pci_cfg_setup(dev_info_t *dip) 48 { 49 pci_regspec_t reg; 50 int i; 51 52 reg.pci_phys_hi = 16 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=16, Func=0 */ 53 reg.pci_phys_mid = 0; 54 reg.pci_phys_low = 0; 55 reg.pci_size_hi = 0; 56 reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */ 57 58 for (i = 0; i < NB_PCI_NFUNC; i++) { 59 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 60 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 61 cmn_err(CE_WARN, 62 "nb_pci_cfg_setup: cannot create reg property"); 63 64 if (pci_config_setup(dip, &dev_16_hdl[i]) != DDI_SUCCESS) 65 cmn_err(CE_WARN, 66 "intel_nb5000: pci_config_setup failed"); 67 reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT; 68 } 69 reg.pci_phys_hi = 17 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=17, Func=0 */ 70 for (i = 0; i < NB_PCI_NFUNC; i++) { 71 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 72 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 73 cmn_err(CE_WARN, 74 "nb_pci_cfg_setup: cannot create reg property"); 75 76 if (pci_config_setup(dip, &dev_17_hdl[i]) != DDI_SUCCESS) 77 cmn_err(CE_WARN, 78 "intel_nb5000: pci_config_setup failed"); 79 reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT; 80 } 81 reg.pci_phys_hi = 21 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=21, Func=0 */ 82 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 83 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 84 cmn_err(CE_WARN, 85 "nb_pci_cfg_setup: cannot create reg property"); 86 if (pci_config_setup(dip, &dev_21_hdl) != DDI_SUCCESS) 87 cmn_err(CE_WARN, "intel_nb5000: pci_config_setup failed"); 88 reg.pci_phys_hi = 22 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=22, Func=0 */ 89 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 90 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 91 cmn_err(CE_WARN, 92 "nb_pci_cfg_setup: cannot create reg property"); 93 if (pci_config_setup(dip, &dev_22_hdl) != DDI_SUCCESS) 94 cmn_err(CE_WARN, "intel_nb5000: pci_config_setup failed"); 95 reg.pci_phys_hi = 0; /* Bus=0, Dev=0, Func=0 */ 96 for (i = 0; i < NB_PCI_DEV; i++) { 97 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 98 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 99 cmn_err(CE_WARN, 100 "nb_pci_cfg_setup: cannot create reg property"); 101 102 if (pci_config_setup(dip, &dev_pci_hdl[i]) != DDI_SUCCESS) 103 cmn_err(CE_WARN, 104 "intel_nb5000: pci_config_setup failed"); 105 reg.pci_phys_hi += 1 << PCI_REG_DEV_SHIFT; 106 } 107 ddi_prop_remove_all(dip); 108 } 109 110 void 111 nb_pci_cfg_free() 112 { 113 int i; 114 115 for (i = 0; i < NB_PCI_NFUNC; i++) { 116 pci_config_teardown(&dev_16_hdl[i]); 117 } 118 for (i = 0; i < NB_PCI_NFUNC; i++) { 119 pci_config_teardown(&dev_17_hdl[i]); 120 } 121 pci_config_teardown(&dev_21_hdl); 122 pci_config_teardown(&dev_22_hdl); 123 for (i = 0; i < NB_PCI_DEV; i++) 124 pci_config_teardown(&dev_pci_hdl[i]); 125 } 126 127 static ddi_acc_handle_t 128 nb_get_hdl(int bus, int dev, int func) 129 { 130 ddi_acc_handle_t hdl; 131 132 if (bus == 0 && dev == 16 && func < NB_PCI_NFUNC) { 133 hdl = dev_16_hdl[func]; 134 } else if (bus == 0 && dev == 17 && func < NB_PCI_NFUNC) { 135 hdl = dev_17_hdl[func]; 136 } else if (bus == 0 && dev < NB_PCI_DEV && func == 0) { 137 hdl = dev_pci_hdl[dev]; 138 } else if (bus == 0 && dev == 21 && func == 0) { 139 hdl = dev_21_hdl; 140 } else if (bus == 0 && dev == 22 && func == 0) { 141 hdl = dev_22_hdl; 142 } else { 143 hdl = 0; 144 } 145 return (hdl); 146 } 147 148 uint8_t 149 nb_pci_getb(int bus, int dev, int func, int reg, int *interpose) 150 { 151 ddi_acc_handle_t hdl; 152 153 hdl = nb_get_hdl(bus, dev, func); 154 return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl)); 155 } 156 157 uint16_t 158 nb_pci_getw(int bus, int dev, int func, int reg, int *interpose) 159 { 160 ddi_acc_handle_t hdl; 161 162 hdl = nb_get_hdl(bus, dev, func); 163 return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl)); 164 } 165 166 uint32_t 167 nb_pci_getl(int bus, int dev, int func, int reg, int *interpose) 168 { 169 ddi_acc_handle_t hdl; 170 171 hdl = nb_get_hdl(bus, dev, func); 172 return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl)); 173 } 174 175 void 176 nb_pci_putb(int bus, int dev, int func, int reg, uint8_t val) 177 { 178 ddi_acc_handle_t hdl; 179 180 hdl = nb_get_hdl(bus, dev, func); 181 cmi_pci_putb(bus, dev, func, reg, hdl, val); 182 } 183 184 void 185 nb_pci_putw(int bus, int dev, int func, int reg, uint16_t val) 186 { 187 ddi_acc_handle_t hdl; 188 189 hdl = nb_get_hdl(bus, dev, func); 190 cmi_pci_putw(bus, dev, func, reg, hdl, val); 191 } 192 193 void 194 nb_pci_putl(int bus, int dev, int func, int reg, uint32_t val) 195 { 196 ddi_acc_handle_t hdl; 197 198 hdl = nb_get_hdl(bus, dev, func); 199 cmi_pci_putl(bus, dev, func, reg, hdl, val); 200 } 201