xref: /onnv-gate/usr/src/uts/intel/io/intel_nb5000/nb_pci_cfg.c (revision 10049:b4b11e684225)
17532SSean.Ye@Sun.COM /*
27532SSean.Ye@Sun.COM  * CDDL HEADER START
37532SSean.Ye@Sun.COM  *
47532SSean.Ye@Sun.COM  * The contents of this file are subject to the terms of the
57532SSean.Ye@Sun.COM  * Common Development and Distribution License (the "License").
67532SSean.Ye@Sun.COM  * You may not use this file except in compliance with the License.
77532SSean.Ye@Sun.COM  *
87532SSean.Ye@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97532SSean.Ye@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107532SSean.Ye@Sun.COM  * See the License for the specific language governing permissions
117532SSean.Ye@Sun.COM  * and limitations under the License.
127532SSean.Ye@Sun.COM  *
137532SSean.Ye@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147532SSean.Ye@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157532SSean.Ye@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167532SSean.Ye@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177532SSean.Ye@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187532SSean.Ye@Sun.COM  *
197532SSean.Ye@Sun.COM  * CDDL HEADER END
207532SSean.Ye@Sun.COM  */
217532SSean.Ye@Sun.COM 
227532SSean.Ye@Sun.COM /*
239783SAdrian.Frost@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247532SSean.Ye@Sun.COM  * Use is subject to license terms.
257532SSean.Ye@Sun.COM  */
267532SSean.Ye@Sun.COM 
277532SSean.Ye@Sun.COM #include <sys/types.h>
287532SSean.Ye@Sun.COM #include <sys/cmn_err.h>
297532SSean.Ye@Sun.COM #include <sys/errno.h>
307532SSean.Ye@Sun.COM #include <sys/systm.h>
317532SSean.Ye@Sun.COM #include <sys/sunddi.h>
327532SSean.Ye@Sun.COM #include <sys/pci_cfgspace.h>
337532SSean.Ye@Sun.COM #include <sys/pci.h>
347532SSean.Ye@Sun.COM #include <sys/pcie.h>
357532SSean.Ye@Sun.COM #include <vm/seg_kmem.h>
367532SSean.Ye@Sun.COM #include <sys/mman.h>
377532SSean.Ye@Sun.COM #include <sys/cpu_module.h>
387532SSean.Ye@Sun.COM #include "nb5000.h"
397532SSean.Ye@Sun.COM 
407532SSean.Ye@Sun.COM static ddi_acc_handle_t dev_16_hdl[NB_PCI_NFUNC];
417532SSean.Ye@Sun.COM static ddi_acc_handle_t dev_17_hdl[NB_PCI_NFUNC];
42*10049SVuong.Nguyen@Sun.COM static ddi_acc_handle_t dev_21_hdl;
43*10049SVuong.Nguyen@Sun.COM static ddi_acc_handle_t dev_22_hdl;
447532SSean.Ye@Sun.COM static ddi_acc_handle_t dev_pci_hdl[NB_PCI_DEV];
457532SSean.Ye@Sun.COM 
467532SSean.Ye@Sun.COM void
nb_pci_cfg_setup(dev_info_t * dip)477532SSean.Ye@Sun.COM nb_pci_cfg_setup(dev_info_t *dip)
487532SSean.Ye@Sun.COM {
497532SSean.Ye@Sun.COM 	pci_regspec_t reg;
507532SSean.Ye@Sun.COM 	int i;
517532SSean.Ye@Sun.COM 
527532SSean.Ye@Sun.COM 	reg.pci_phys_hi = 16 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=16, Func=0 */
537532SSean.Ye@Sun.COM 	reg.pci_phys_mid = 0;
547532SSean.Ye@Sun.COM 	reg.pci_phys_low = 0;
557532SSean.Ye@Sun.COM 	reg.pci_size_hi = 0;
567532SSean.Ye@Sun.COM 	reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */
577532SSean.Ye@Sun.COM 
587532SSean.Ye@Sun.COM 	for (i = 0; i < NB_PCI_NFUNC; i++) {
597532SSean.Ye@Sun.COM 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
607532SSean.Ye@Sun.COM 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
617532SSean.Ye@Sun.COM 		cmn_err(CE_WARN,
627532SSean.Ye@Sun.COM 		    "nb_pci_cfg_setup: cannot create reg property");
637532SSean.Ye@Sun.COM 
647532SSean.Ye@Sun.COM 		if (pci_config_setup(dip, &dev_16_hdl[i]) != DDI_SUCCESS)
657532SSean.Ye@Sun.COM 			cmn_err(CE_WARN,
667532SSean.Ye@Sun.COM 			    "intel_nb5000: pci_config_setup failed");
677532SSean.Ye@Sun.COM 		reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT;
687532SSean.Ye@Sun.COM 	}
697532SSean.Ye@Sun.COM 	reg.pci_phys_hi = 17 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=17, Func=0 */
707532SSean.Ye@Sun.COM 	for (i = 0; i < NB_PCI_NFUNC; i++) {
717532SSean.Ye@Sun.COM 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
727532SSean.Ye@Sun.COM 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
737532SSean.Ye@Sun.COM 		cmn_err(CE_WARN,
747532SSean.Ye@Sun.COM 		    "nb_pci_cfg_setup: cannot create reg property");
757532SSean.Ye@Sun.COM 
767532SSean.Ye@Sun.COM 		if (pci_config_setup(dip, &dev_17_hdl[i]) != DDI_SUCCESS)
777532SSean.Ye@Sun.COM 			cmn_err(CE_WARN,
787532SSean.Ye@Sun.COM 			    "intel_nb5000: pci_config_setup failed");
797532SSean.Ye@Sun.COM 		reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT;
807532SSean.Ye@Sun.COM 	}
81*10049SVuong.Nguyen@Sun.COM 	reg.pci_phys_hi = 21 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=21, Func=0 */
82*10049SVuong.Nguyen@Sun.COM 	if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
83*10049SVuong.Nguyen@Sun.COM 	    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
84*10049SVuong.Nguyen@Sun.COM 		cmn_err(CE_WARN,
85*10049SVuong.Nguyen@Sun.COM 		    "nb_pci_cfg_setup: cannot create reg property");
86*10049SVuong.Nguyen@Sun.COM 	if (pci_config_setup(dip, &dev_21_hdl) != DDI_SUCCESS)
87*10049SVuong.Nguyen@Sun.COM 		cmn_err(CE_WARN, "intel_nb5000: pci_config_setup failed");
88*10049SVuong.Nguyen@Sun.COM 	reg.pci_phys_hi = 22 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=22, Func=0 */
89*10049SVuong.Nguyen@Sun.COM 	if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
90*10049SVuong.Nguyen@Sun.COM 	    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
91*10049SVuong.Nguyen@Sun.COM 		cmn_err(CE_WARN,
92*10049SVuong.Nguyen@Sun.COM 		    "nb_pci_cfg_setup: cannot create reg property");
93*10049SVuong.Nguyen@Sun.COM 	if (pci_config_setup(dip, &dev_22_hdl) != DDI_SUCCESS)
94*10049SVuong.Nguyen@Sun.COM 		cmn_err(CE_WARN, "intel_nb5000: pci_config_setup failed");
957532SSean.Ye@Sun.COM 	reg.pci_phys_hi = 0;		/* Bus=0, Dev=0, Func=0 */
967532SSean.Ye@Sun.COM 	for (i = 0; i < NB_PCI_DEV; i++) {
977532SSean.Ye@Sun.COM 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
987532SSean.Ye@Sun.COM 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
997532SSean.Ye@Sun.COM 		cmn_err(CE_WARN,
1007532SSean.Ye@Sun.COM 		    "nb_pci_cfg_setup: cannot create reg property");
1017532SSean.Ye@Sun.COM 
1027532SSean.Ye@Sun.COM 		if (pci_config_setup(dip, &dev_pci_hdl[i]) != DDI_SUCCESS)
1037532SSean.Ye@Sun.COM 			cmn_err(CE_WARN,
1047532SSean.Ye@Sun.COM 			    "intel_nb5000: pci_config_setup failed");
1057532SSean.Ye@Sun.COM 		reg.pci_phys_hi += 1 << PCI_REG_DEV_SHIFT;
1067532SSean.Ye@Sun.COM 	}
1079783SAdrian.Frost@Sun.COM 	ddi_prop_remove_all(dip);
1087532SSean.Ye@Sun.COM }
1097532SSean.Ye@Sun.COM 
1107532SSean.Ye@Sun.COM void
nb_pci_cfg_free()1117532SSean.Ye@Sun.COM nb_pci_cfg_free()
1127532SSean.Ye@Sun.COM {
1137532SSean.Ye@Sun.COM 	int i;
1147532SSean.Ye@Sun.COM 
1157532SSean.Ye@Sun.COM 	for (i = 0; i < NB_PCI_NFUNC; i++) {
1167532SSean.Ye@Sun.COM 		pci_config_teardown(&dev_16_hdl[i]);
1177532SSean.Ye@Sun.COM 	}
1187532SSean.Ye@Sun.COM 	for (i = 0; i < NB_PCI_NFUNC; i++) {
1197532SSean.Ye@Sun.COM 		pci_config_teardown(&dev_17_hdl[i]);
1207532SSean.Ye@Sun.COM 	}
121*10049SVuong.Nguyen@Sun.COM 	pci_config_teardown(&dev_21_hdl);
122*10049SVuong.Nguyen@Sun.COM 	pci_config_teardown(&dev_22_hdl);
1237532SSean.Ye@Sun.COM 	for (i = 0; i < NB_PCI_DEV; i++)
1247532SSean.Ye@Sun.COM 		pci_config_teardown(&dev_pci_hdl[i]);
1257532SSean.Ye@Sun.COM }
1267532SSean.Ye@Sun.COM 
1277532SSean.Ye@Sun.COM static ddi_acc_handle_t
nb_get_hdl(int bus,int dev,int func)1287532SSean.Ye@Sun.COM nb_get_hdl(int bus, int dev, int func)
1297532SSean.Ye@Sun.COM {
1307532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1317532SSean.Ye@Sun.COM 
1327532SSean.Ye@Sun.COM 	if (bus == 0 && dev == 16 && func < NB_PCI_NFUNC) {
1337532SSean.Ye@Sun.COM 		hdl = dev_16_hdl[func];
1347532SSean.Ye@Sun.COM 	} else if (bus == 0 && dev == 17 && func < NB_PCI_NFUNC) {
1357532SSean.Ye@Sun.COM 		hdl = dev_17_hdl[func];
1367532SSean.Ye@Sun.COM 	} else if (bus == 0 && dev < NB_PCI_DEV && func == 0) {
1377532SSean.Ye@Sun.COM 		hdl = dev_pci_hdl[dev];
138*10049SVuong.Nguyen@Sun.COM 	} else if (bus == 0 && dev == 21 && func == 0) {
139*10049SVuong.Nguyen@Sun.COM 		hdl = dev_21_hdl;
140*10049SVuong.Nguyen@Sun.COM 	} else if (bus == 0 && dev == 22 && func == 0) {
141*10049SVuong.Nguyen@Sun.COM 		hdl = dev_22_hdl;
1427532SSean.Ye@Sun.COM 	} else {
1437532SSean.Ye@Sun.COM 		hdl = 0;
1447532SSean.Ye@Sun.COM 	}
1457532SSean.Ye@Sun.COM 	return (hdl);
1467532SSean.Ye@Sun.COM }
1477532SSean.Ye@Sun.COM 
1487532SSean.Ye@Sun.COM uint8_t
nb_pci_getb(int bus,int dev,int func,int reg,int * interpose)1497532SSean.Ye@Sun.COM nb_pci_getb(int bus, int dev, int func, int reg, int *interpose)
1507532SSean.Ye@Sun.COM {
1517532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1527532SSean.Ye@Sun.COM 
1537532SSean.Ye@Sun.COM 	hdl = nb_get_hdl(bus, dev, func);
1547532SSean.Ye@Sun.COM 	return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl));
1557532SSean.Ye@Sun.COM }
1567532SSean.Ye@Sun.COM 
1577532SSean.Ye@Sun.COM uint16_t
nb_pci_getw(int bus,int dev,int func,int reg,int * interpose)1587532SSean.Ye@Sun.COM nb_pci_getw(int bus, int dev, int func, int reg, int *interpose)
1597532SSean.Ye@Sun.COM {
1607532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1617532SSean.Ye@Sun.COM 
1627532SSean.Ye@Sun.COM 	hdl = nb_get_hdl(bus, dev, func);
1637532SSean.Ye@Sun.COM 	return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl));
1647532SSean.Ye@Sun.COM }
1657532SSean.Ye@Sun.COM 
1667532SSean.Ye@Sun.COM uint32_t
nb_pci_getl(int bus,int dev,int func,int reg,int * interpose)1677532SSean.Ye@Sun.COM nb_pci_getl(int bus, int dev, int func, int reg, int *interpose)
1687532SSean.Ye@Sun.COM {
1697532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1707532SSean.Ye@Sun.COM 
1717532SSean.Ye@Sun.COM 	hdl = nb_get_hdl(bus, dev, func);
1727532SSean.Ye@Sun.COM 	return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl));
1737532SSean.Ye@Sun.COM }
1747532SSean.Ye@Sun.COM 
1757532SSean.Ye@Sun.COM void
nb_pci_putb(int bus,int dev,int func,int reg,uint8_t val)1767532SSean.Ye@Sun.COM nb_pci_putb(int bus, int dev, int func, int reg, uint8_t val)
1777532SSean.Ye@Sun.COM {
1787532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1797532SSean.Ye@Sun.COM 
1807532SSean.Ye@Sun.COM 	hdl = nb_get_hdl(bus, dev, func);
1817532SSean.Ye@Sun.COM 	cmi_pci_putb(bus, dev, func, reg, hdl, val);
1827532SSean.Ye@Sun.COM }
1837532SSean.Ye@Sun.COM 
1847532SSean.Ye@Sun.COM void
nb_pci_putw(int bus,int dev,int func,int reg,uint16_t val)1857532SSean.Ye@Sun.COM nb_pci_putw(int bus, int dev, int func, int reg, uint16_t val)
1867532SSean.Ye@Sun.COM {
1877532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1887532SSean.Ye@Sun.COM 
1897532SSean.Ye@Sun.COM 	hdl = nb_get_hdl(bus, dev, func);
1907532SSean.Ye@Sun.COM 	cmi_pci_putw(bus, dev, func, reg, hdl, val);
1917532SSean.Ye@Sun.COM }
1927532SSean.Ye@Sun.COM 
1937532SSean.Ye@Sun.COM void
nb_pci_putl(int bus,int dev,int func,int reg,uint32_t val)1947532SSean.Ye@Sun.COM nb_pci_putl(int bus, int dev, int func, int reg, uint32_t val)
1957532SSean.Ye@Sun.COM {
1967532SSean.Ye@Sun.COM 	ddi_acc_handle_t hdl;
1977532SSean.Ye@Sun.COM 
1987532SSean.Ye@Sun.COM 	hdl = nb_get_hdl(bus, dev, func);
1997532SSean.Ye@Sun.COM 	cmi_pci_putl(bus, dev, func, reg, hdl, val);
2007532SSean.Ye@Sun.COM }
201