120c794b3Sgavinm /*
220c794b3Sgavinm  * CDDL HEADER START
320c794b3Sgavinm  *
420c794b3Sgavinm  * The contents of this file are subject to the terms of the
520c794b3Sgavinm  * Common Development and Distribution License (the "License").
620c794b3Sgavinm  * You may not use this file except in compliance with the License.
720c794b3Sgavinm  *
820c794b3Sgavinm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
920c794b3Sgavinm  * or http://www.opensolaris.org/os/licensing.
1020c794b3Sgavinm  * See the License for the specific language governing permissions
1120c794b3Sgavinm  * and limitations under the License.
1220c794b3Sgavinm  *
1320c794b3Sgavinm  * When distributing Covered Code, include this CDDL HEADER in each
1420c794b3Sgavinm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1520c794b3Sgavinm  * If applicable, add the following below this CDDL HEADER, with the
1620c794b3Sgavinm  * fields enclosed by brackets "[]" replaced with your own identifying
1720c794b3Sgavinm  * information: Portions Copyright [yyyy] [name of copyright owner]
1820c794b3Sgavinm  *
1920c794b3Sgavinm  * CDDL HEADER END
2020c794b3Sgavinm  */
2120c794b3Sgavinm 
2220c794b3Sgavinm /*
239ff4cbe7SAdrian Frost  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2420c794b3Sgavinm  * Use is subject to license terms.
2520c794b3Sgavinm  */
2620c794b3Sgavinm 
2720c794b3Sgavinm #include <sys/types.h>
2820c794b3Sgavinm #include <sys/cmn_err.h>
2920c794b3Sgavinm #include <sys/errno.h>
3020c794b3Sgavinm #include <sys/systm.h>
3120c794b3Sgavinm #include <sys/sunddi.h>
3220c794b3Sgavinm #include <sys/pci_cfgspace.h>
3320c794b3Sgavinm #include <sys/pci.h>
3420c794b3Sgavinm #include <sys/pcie.h>
3520c794b3Sgavinm #include <vm/seg_kmem.h>
3620c794b3Sgavinm #include <sys/mman.h>
3720c794b3Sgavinm #include <sys/cpu_module.h>
3820c794b3Sgavinm #include "nb5000.h"
3920c794b3Sgavinm 
4020c794b3Sgavinm static ddi_acc_handle_t dev_16_hdl[NB_PCI_NFUNC];
4120c794b3Sgavinm static ddi_acc_handle_t dev_17_hdl[NB_PCI_NFUNC];
42*85738508SVuong Nguyen static ddi_acc_handle_t dev_21_hdl;
43*85738508SVuong Nguyen static ddi_acc_handle_t dev_22_hdl;
4420c794b3Sgavinm static ddi_acc_handle_t dev_pci_hdl[NB_PCI_DEV];
4520c794b3Sgavinm 
4620c794b3Sgavinm void
nb_pci_cfg_setup(dev_info_t * dip)4720c794b3Sgavinm nb_pci_cfg_setup(dev_info_t *dip)
4820c794b3Sgavinm {
4920c794b3Sgavinm 	pci_regspec_t reg;
5020c794b3Sgavinm 	int i;
5120c794b3Sgavinm 
5220c794b3Sgavinm 	reg.pci_phys_hi = 16 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=16, Func=0 */
5320c794b3Sgavinm 	reg.pci_phys_mid = 0;
5420c794b3Sgavinm 	reg.pci_phys_low = 0;
5520c794b3Sgavinm 	reg.pci_size_hi = 0;
5620c794b3Sgavinm 	reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */
5720c794b3Sgavinm 
5820c794b3Sgavinm 	for (i = 0; i < NB_PCI_NFUNC; i++) {
5920c794b3Sgavinm 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
6020c794b3Sgavinm 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
6120c794b3Sgavinm 		cmn_err(CE_WARN,
6220c794b3Sgavinm 		    "nb_pci_cfg_setup: cannot create reg property");
6320c794b3Sgavinm 
6420c794b3Sgavinm 		if (pci_config_setup(dip, &dev_16_hdl[i]) != DDI_SUCCESS)
6520c794b3Sgavinm 			cmn_err(CE_WARN,
6620c794b3Sgavinm 			    "intel_nb5000: pci_config_setup failed");
6720c794b3Sgavinm 		reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT;
6820c794b3Sgavinm 	}
6920c794b3Sgavinm 	reg.pci_phys_hi = 17 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=17, Func=0 */
7020c794b3Sgavinm 	for (i = 0; i < NB_PCI_NFUNC; i++) {
7120c794b3Sgavinm 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
7220c794b3Sgavinm 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
7320c794b3Sgavinm 		cmn_err(CE_WARN,
7420c794b3Sgavinm 		    "nb_pci_cfg_setup: cannot create reg property");
7520c794b3Sgavinm 
7620c794b3Sgavinm 		if (pci_config_setup(dip, &dev_17_hdl[i]) != DDI_SUCCESS)
7720c794b3Sgavinm 			cmn_err(CE_WARN,
7820c794b3Sgavinm 			    "intel_nb5000: pci_config_setup failed");
7920c794b3Sgavinm 		reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT;
8020c794b3Sgavinm 	}
81*85738508SVuong Nguyen 	reg.pci_phys_hi = 21 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=21, Func=0 */
82*85738508SVuong Nguyen 	if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
83*85738508SVuong Nguyen 	    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
84*85738508SVuong Nguyen 		cmn_err(CE_WARN,
85*85738508SVuong Nguyen 		    "nb_pci_cfg_setup: cannot create reg property");
86*85738508SVuong Nguyen 	if (pci_config_setup(dip, &dev_21_hdl) != DDI_SUCCESS)
87*85738508SVuong Nguyen 		cmn_err(CE_WARN, "intel_nb5000: pci_config_setup failed");
88*85738508SVuong Nguyen 	reg.pci_phys_hi = 22 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=22, Func=0 */
89*85738508SVuong Nguyen 	if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
90*85738508SVuong Nguyen 	    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
91*85738508SVuong Nguyen 		cmn_err(CE_WARN,
92*85738508SVuong Nguyen 		    "nb_pci_cfg_setup: cannot create reg property");
93*85738508SVuong Nguyen 	if (pci_config_setup(dip, &dev_22_hdl) != DDI_SUCCESS)
94*85738508SVuong Nguyen 		cmn_err(CE_WARN, "intel_nb5000: pci_config_setup failed");
9520c794b3Sgavinm 	reg.pci_phys_hi = 0;		/* Bus=0, Dev=0, Func=0 */
9620c794b3Sgavinm 	for (i = 0; i < NB_PCI_DEV; i++) {
9720c794b3Sgavinm 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
9820c794b3Sgavinm 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
9920c794b3Sgavinm 		cmn_err(CE_WARN,
10020c794b3Sgavinm 		    "nb_pci_cfg_setup: cannot create reg property");
10120c794b3Sgavinm 
10220c794b3Sgavinm 		if (pci_config_setup(dip, &dev_pci_hdl[i]) != DDI_SUCCESS)
10320c794b3Sgavinm 			cmn_err(CE_WARN,
10420c794b3Sgavinm 			    "intel_nb5000: pci_config_setup failed");
10520c794b3Sgavinm 		reg.pci_phys_hi += 1 << PCI_REG_DEV_SHIFT;
10620c794b3Sgavinm 	}
1079ff4cbe7SAdrian Frost 	ddi_prop_remove_all(dip);
10820c794b3Sgavinm }
10920c794b3Sgavinm 
11020c794b3Sgavinm void
nb_pci_cfg_free()11120c794b3Sgavinm nb_pci_cfg_free()
11220c794b3Sgavinm {
11320c794b3Sgavinm 	int i;
11420c794b3Sgavinm 
11520c794b3Sgavinm 	for (i = 0; i < NB_PCI_NFUNC; i++) {
11620c794b3Sgavinm 		pci_config_teardown(&dev_16_hdl[i]);
11720c794b3Sgavinm 	}
11820c794b3Sgavinm 	for (i = 0; i < NB_PCI_NFUNC; i++) {
11920c794b3Sgavinm 		pci_config_teardown(&dev_17_hdl[i]);
12020c794b3Sgavinm 	}
121*85738508SVuong Nguyen 	pci_config_teardown(&dev_21_hdl);
122*85738508SVuong Nguyen 	pci_config_teardown(&dev_22_hdl);
12320c794b3Sgavinm 	for (i = 0; i < NB_PCI_DEV; i++)
12420c794b3Sgavinm 		pci_config_teardown(&dev_pci_hdl[i]);
12520c794b3Sgavinm }
12620c794b3Sgavinm 
12720c794b3Sgavinm static ddi_acc_handle_t
nb_get_hdl(int bus,int dev,int func)12820c794b3Sgavinm nb_get_hdl(int bus, int dev, int func)
12920c794b3Sgavinm {
13020c794b3Sgavinm 	ddi_acc_handle_t hdl;
13120c794b3Sgavinm 
13220c794b3Sgavinm 	if (bus == 0 && dev == 16 && func < NB_PCI_NFUNC) {
13320c794b3Sgavinm 		hdl = dev_16_hdl[func];
13420c794b3Sgavinm 	} else if (bus == 0 && dev == 17 && func < NB_PCI_NFUNC) {
13520c794b3Sgavinm 		hdl = dev_17_hdl[func];
13620c794b3Sgavinm 	} else if (bus == 0 && dev < NB_PCI_DEV && func == 0) {
13720c794b3Sgavinm 		hdl = dev_pci_hdl[dev];
138*85738508SVuong Nguyen 	} else if (bus == 0 && dev == 21 && func == 0) {
139*85738508SVuong Nguyen 		hdl = dev_21_hdl;
140*85738508SVuong Nguyen 	} else if (bus == 0 && dev == 22 && func == 0) {
141*85738508SVuong Nguyen 		hdl = dev_22_hdl;
14220c794b3Sgavinm 	} else {
14320c794b3Sgavinm 		hdl = 0;
14420c794b3Sgavinm 	}
14520c794b3Sgavinm 	return (hdl);
14620c794b3Sgavinm }
14720c794b3Sgavinm 
14820c794b3Sgavinm uint8_t
nb_pci_getb(int bus,int dev,int func,int reg,int * interpose)14920c794b3Sgavinm nb_pci_getb(int bus, int dev, int func, int reg, int *interpose)
15020c794b3Sgavinm {
15120c794b3Sgavinm 	ddi_acc_handle_t hdl;
15220c794b3Sgavinm 
15320c794b3Sgavinm 	hdl = nb_get_hdl(bus, dev, func);
15420c794b3Sgavinm 	return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl));
15520c794b3Sgavinm }
15620c794b3Sgavinm 
15720c794b3Sgavinm uint16_t
nb_pci_getw(int bus,int dev,int func,int reg,int * interpose)15820c794b3Sgavinm nb_pci_getw(int bus, int dev, int func, int reg, int *interpose)
15920c794b3Sgavinm {
16020c794b3Sgavinm 	ddi_acc_handle_t hdl;
16120c794b3Sgavinm 
16220c794b3Sgavinm 	hdl = nb_get_hdl(bus, dev, func);
16320c794b3Sgavinm 	return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl));
16420c794b3Sgavinm }
16520c794b3Sgavinm 
16620c794b3Sgavinm uint32_t
nb_pci_getl(int bus,int dev,int func,int reg,int * interpose)16720c794b3Sgavinm nb_pci_getl(int bus, int dev, int func, int reg, int *interpose)
16820c794b3Sgavinm {
16920c794b3Sgavinm 	ddi_acc_handle_t hdl;
17020c794b3Sgavinm 
17120c794b3Sgavinm 	hdl = nb_get_hdl(bus, dev, func);
17220c794b3Sgavinm 	return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl));
17320c794b3Sgavinm }
17420c794b3Sgavinm 
17520c794b3Sgavinm void
nb_pci_putb(int bus,int dev,int func,int reg,uint8_t val)17620c794b3Sgavinm nb_pci_putb(int bus, int dev, int func, int reg, uint8_t val)
17720c794b3Sgavinm {
17820c794b3Sgavinm 	ddi_acc_handle_t hdl;
17920c794b3Sgavinm 
18020c794b3Sgavinm 	hdl = nb_get_hdl(bus, dev, func);
18120c794b3Sgavinm 	cmi_pci_putb(bus, dev, func, reg, hdl, val);
18220c794b3Sgavinm }
18320c794b3Sgavinm 
18420c794b3Sgavinm void
nb_pci_putw(int bus,int dev,int func,int reg,uint16_t val)18520c794b3Sgavinm nb_pci_putw(int bus, int dev, int func, int reg, uint16_t val)
18620c794b3Sgavinm {
18720c794b3Sgavinm 	ddi_acc_handle_t hdl;
18820c794b3Sgavinm 
18920c794b3Sgavinm 	hdl = nb_get_hdl(bus, dev, func);
19020c794b3Sgavinm 	cmi_pci_putw(bus, dev, func, reg, hdl, val);
19120c794b3Sgavinm }
19220c794b3Sgavinm 
19320c794b3Sgavinm void
nb_pci_putl(int bus,int dev,int func,int reg,uint32_t val)19420c794b3Sgavinm nb_pci_putl(int bus, int dev, int func, int reg, uint32_t val)
19520c794b3Sgavinm {
19620c794b3Sgavinm 	ddi_acc_handle_t hdl;
19720c794b3Sgavinm 
19820c794b3Sgavinm 	hdl = nb_get_hdl(bus, dev, func);
19920c794b3Sgavinm 	cmi_pci_putl(bus, dev, func, reg, hdl, val);
20020c794b3Sgavinm }
201