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 *)®, 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 *)®, 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 *)®, 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 *)®, 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 *)®, 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