View | Details | Raw Unified | Return to bug 248514
Collapse All | Expand All

(-)sys/dev/imcsmb/imcsmb_pci.c (-29 / +69 lines)
Lines 51-66 Link Here
51
#include "imcsmb_reg.h"
51
#include "imcsmb_reg.h"
52
#include "imcsmb_var.h"
52
#include "imcsmb_var.h"
53
53
54
/* (Sandy,Ivy)bridge-Xeon and (Has,Broad)well-Xeon CPUs contain one or two
54
/* (Sandy,Ivy)bridge-Xeon, (Has,Broad)well-Xeon, and Skylake-Xeon CPUs contain
55
 * "Integrated Memory Controllers" (iMCs), and each iMC contains two separate
55
 * one or two "Integrated Memory Controllers" (iMCs), and each iMC contains
56
 * SMBus controllers. These are used for reading SPD data from the DIMMs, and
56
 * two separate SMBus controllers. These are used for reading SPD data from the
57
 * for reading the "Thermal Sensor on DIMM" (TSODs). The iMC SMBus controllers
57
 * DIMMs, and for reading the "Thermal Sensor on DIMM" (TSODs). The iMC SMBus
58
 * are very simple devices, and have limited functionality compared to
58
 * controllers are very simple devices, and have limited functionality compared
59
 * full-fledged SMBus controllers, like the one in Intel ICHs and PCHs.
59
 * to full-fledged SMBus controllers, like the one in Intel ICHs and PCHs.
60
 *
60
 *
61
 * The publicly available documentation for the iMC SMBus controllers can be
61
 * The publicly available documentation for the iMC SMBus controllers can be
62
 * found in the CPU datasheets for (Sandy,Ivy)bridge-Xeon and
62
 * found in the CPU datasheets for (Sandy,Ivy)bridge-Xeon, (Has,Broad)well-Xeon,
63
 * (Has,broad)well-Xeon, respectively:
63
 * and Skylake-Xeon, respectively:
64
 *
64
 *
65
 * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/
65
 * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/
66
 *      Sandybridge     xeon-e5-1600-2600-vol-2-datasheet.pdf
66
 *      Sandybridge     xeon-e5-1600-2600-vol-2-datasheet.pdf
Lines 67-72 Link Here
67
 *      Ivybridge       xeon-e5-v2-datasheet-vol-2.pdf
67
 *      Ivybridge       xeon-e5-v2-datasheet-vol-2.pdf
68
 *      Haswell         xeon-e5-v3-datasheet-vol-2.pdf
68
 *      Haswell         xeon-e5-v3-datasheet-vol-2.pdf
69
 *      Broadwell       xeon-e5-v4-datasheet-vol-2.pdf
69
 *      Broadwell       xeon-e5-v4-datasheet-vol-2.pdf
70
 *      Skylake         xeon-scalable-datasheet-vol-2.pdf
70
 *
71
 *
71
 * Another useful resource is the Linux driver. It is not in the main tree.
72
 * Another useful resource is the Linux driver. It is not in the main tree.
72
 *
73
 *
Lines 101-149 Link Here
101
 * driver such as this one.
102
 * driver such as this one.
102
 */
103
 */
103
104
104
/* PCIe device IDs for (Sandy,Ivy)bridge)-Xeon and (Has,Broad)well-Xeon */
105
/* PCIe device IDs for (Sandy,Ivy)bridge)-Xeon, (Has,Broad)well-Xeon, and
106
 * Skylake-Xeon
107
 */
105
#define PCI_VENDOR_INTEL		0x8086
108
#define PCI_VENDOR_INTEL		0x8086
106
#define IMCSMB_PCI_DEV_ID_IMC0_SBX	0x3ca8
109
#define IMCSMB_PCI_DEV_ID_IMC0_SBX	0x3ca8
107
#define IMCSMB_PCI_DEV_ID_IMC0_IBX	0x0ea8
110
#define IMCSMB_PCI_DEV_ID_IMC0_IBX	0x0ea8
108
#define IMCSMB_PCI_DEV_ID_IMC0_HSX	0x2fa8
111
#define IMCSMB_PCI_DEV_ID_IMC0_HSX	0x2fa8
109
#define IMCSMB_PCI_DEV_ID_IMC0_BDX	0x6fa8
112
#define IMCSMB_PCI_DEV_ID_IMC0_BDX	0x6fa8
110
/* (Sandy,Ivy)bridge-Xeon only have a single memory controller per socket */
113
#define IMCSMB_PCI_DEV_ID_IMC0_SLX	0x2085
114
/* Sandybridge-Xeon only has a single memory controller per socket */
115
#define IMCSMB_PCI_DEV_ID_IMC1_IBX	0x0e68
111
#define IMCSMB_PCI_DEV_ID_IMC1_HSX	0x2f68
116
#define IMCSMB_PCI_DEV_ID_IMC1_HSX	0x2f68
112
#define IMCSMB_PCI_DEV_ID_IMC1_BDX	0x6f68
117
#define IMCSMB_PCI_DEV_ID_IMC1_BDX	0x6f68
118
#define IMCSMB_PCI_DEV_ID_IMC1_SLX	0x2086
113
119
114
/* There are two SMBus controllers in each device. These define the registers
120
/* There are two SMBus controllers in each device. These define the registers
115
 * for each of these devices.
121
 * for each of these devices.
116
 */
122
 */
117
static struct imcsmb_reg_set imcsmb_regs[] = {
123
static struct imcsmb_reg_set imcsmb_regs[2];
118
	{
119
		.smb_stat = IMCSMB_REG_STATUS0,
120
		.smb_cmd = IMCSMB_REG_COMMAND0,
121
		.smb_cntl = IMCSMB_REG_CONTROL0
122
	},
123
	{
124
		.smb_stat = IMCSMB_REG_STATUS1,
125
		.smb_cmd = IMCSMB_REG_COMMAND1,
126
		.smb_cntl = IMCSMB_REG_CONTROL1
127
	},
128
};
129
124
130
static struct imcsmb_pci_device {
125
static struct imcsmb_pci_device {
131
	uint16_t	id;
126
	uint16_t	id;
132
	char		*name;
127
	char		*name;
128
	uint16_t	base;
133
} imcsmb_pci_devices[] = {
129
} imcsmb_pci_devices[] = {
134
	{IMCSMB_PCI_DEV_ID_IMC0_SBX,
130
	{IMCSMB_PCI_DEV_ID_IMC0_SBX,
135
	    "Intel Sandybridge Xeon iMC 0 SMBus controllers"	},
131
	    "Intel Sandybridge Xeon iMC 0 SMBus controllers",
132
	    IMCSMB_REG_BASE_SBX},
136
	{IMCSMB_PCI_DEV_ID_IMC0_IBX,
133
	{IMCSMB_PCI_DEV_ID_IMC0_IBX,
137
	    "Intel Ivybridge Xeon iMC 0 SMBus controllers"	},
134
	    "Intel Ivybridge Xeon iMC 0 SMBus controllers",
135
	    IMCSMB_REG_BASE_IBX},
136
	{IMCSMB_PCI_DEV_ID_IMC1_IBX,
137
	    "Intel Ivybridge Xeon iMC 1 SMBus controllers",
138
	    IMCSMB_REG_BASE_IBX},
138
	{IMCSMB_PCI_DEV_ID_IMC0_HSX,
139
	{IMCSMB_PCI_DEV_ID_IMC0_HSX,
139
	    "Intel Haswell Xeon iMC 0 SMBus controllers"	},
140
	    "Intel Haswell Xeon iMC 0 SMBus controllers",
141
	    IMCSMB_REG_BASE_HSX},
140
	{IMCSMB_PCI_DEV_ID_IMC1_HSX,
142
	{IMCSMB_PCI_DEV_ID_IMC1_HSX,
141
	    "Intel Haswell Xeon iMC 1 SMBus controllers"	},
143
	    "Intel Haswell Xeon iMC 1 SMBus controllers",
144
	    IMCSMB_REG_BASE_HSX},
142
	{IMCSMB_PCI_DEV_ID_IMC0_BDX,
145
	{IMCSMB_PCI_DEV_ID_IMC0_BDX,
143
	    "Intel Broadwell Xeon iMC 0 SMBus controllers"	},
146
	    "Intel Broadwell Xeon iMC 0 SMBus controllers",
147
	    IMCSMB_REG_BASE_BDX},
144
	{IMCSMB_PCI_DEV_ID_IMC1_BDX,
148
	{IMCSMB_PCI_DEV_ID_IMC1_BDX,
145
	    "Intel Broadwell Xeon iMC 1 SMBus controllers"	},
149
	    "Intel Broadwell Xeon iMC 1 SMBus controllers",
146
	{0, NULL},
150
	    IMCSMB_REG_BASE_BDX},
151
	{IMCSMB_PCI_DEV_ID_IMC0_SLX,
152
	    "Intel Skylake Xeon iMC 0 SMBus controllers",
153
	    IMCSMB_REG_BASE_SLX},
154
	{IMCSMB_PCI_DEV_ID_IMC1_SLX,
155
	    "Intel Skylake Xeon iMC 1 SMBus controllers",
156
	    IMCSMB_REG_BASE_SLX},
157
	{0, NULL, 0},
147
};
158
};
148
159
149
/* Device methods. */
160
/* Device methods. */
Lines 165-170 Link Here
165
imcsmb_pci_attach(device_t dev)
176
imcsmb_pci_attach(device_t dev)
166
{
177
{
167
	struct imcsmb_pci_softc *sc;
178
	struct imcsmb_pci_softc *sc;
179
	struct imcsmb_pci_device *pci_device;
180
	uint16_t pci_dev_id;
181
	uint16_t base;
168
	device_t child;
182
	device_t child;
169
	int rc;
183
	int rc;
170
	int unit;
184
	int unit;
Lines 174-179 Link Here
174
	sc->dev = dev;
188
	sc->dev = dev;
175
	sc->semaphore = 0;
189
	sc->semaphore = 0;
176
190
191
	/* Walk the list of supported devices again to find the base address;
192
	 * we only get here if imcsmb_pci_probe() found a match, so it
193
	 * shouldn't be possible to end up with 'base' of 0; handle it anyway.
194
	 */
195
	base = 0;
196
	pci_dev_id = pci_get_device(dev);
197
	for (pci_device = imcsmb_pci_devices;
198
	    pci_device->base != 0;
199
	    pci_device++) {
200
		if (pci_dev_id == pci_device->id) {
201
			base = pci_device->base;
202
			break;
203
		}
204
	}
205
	if (base == 0) {
206
		device_printf(dev, "Could not find register base address\n");
207
		rc = ENXIO;
208
		goto out;
209
	}
210
177
	/* Create the imcsmbX children */
211
	/* Create the imcsmbX children */
178
	for (unit = 0; unit < 2; unit++) {
212
	for (unit = 0; unit < 2; unit++) {
179
		child = device_add_child(dev, "imcsmb", -1);
213
		child = device_add_child(dev, "imcsmb", -1);
Lines 183-188 Link Here
183
			rc = ENXIO;
217
			rc = ENXIO;
184
			goto out;
218
			goto out;
185
		}
219
		}
220
		/* Initialize the register array for the base address and
221
		 * unit.
222
		 */
223
		imcsmb_regs[unit].smb_stat = IMCSMB_REG_STATUS(base, unit);
224
		imcsmb_regs[unit].smb_cmd = IMCSMB_REG_COMMAND(base, unit);
225
		imcsmb_regs[unit].smb_cntl = IMCSMB_REG_CONTROL(base, unit);
186
		/* Set the child's ivars to point to the appropriate set of
226
		/* Set the child's ivars to point to the appropriate set of
187
		 * the PCI device's registers.
227
		 * the PCI device's registers.
188
		 */
228
		 */
(-)sys/dev/imcsmb/imcsmb_reg.h (-9 / +16 lines)
Lines 51-59 Link Here
51
51
52
#include <dev/smbus/smbconf.h>
52
#include <dev/smbus/smbconf.h>
53
53
54
/* Intel (Sandy,Ivy)bridge and (Has,Broad)well CPUs have integrated memory
54
/* Intel (Sandy,Ivy)bridge, (Has,Broad)well, and Skylake CPUs have integrated
55
 * controllers (iMCs), each of which having up to two SMBus controllers. They
55
 * memory controllers (iMCs), each of which having up to two SMBus controllers.
56
 * are programmed via sets of registers in the same PCI device, which are
56
 * They are programmed via sets of registers in the same PCI device, which are
57
 * identical other than the register numbers.
57
 * identical other than the register numbers.
58
 *
58
 *
59
 * The full documentation for these registers can be found in volume two of the
59
 * The full documentation for these registers can be found in volume two of the
Lines 60-80 Link Here
60
 * datasheets for the CPUs. Refer to the links in imcsmb_pci.c
60
 * datasheets for the CPUs. Refer to the links in imcsmb_pci.c
61
 */
61
 */
62
62
63
#define	IMCSMB_REG_STATUS0			0x0180
63
/* The base address for the sets of iMC registers is CPU-specific. */
64
#define	IMCSMB_REG_STATUS1			0x0190
64
#define	IMCSMB_REG_BASE_SBX	0x0180
65
#define	IMCSMB_REG_BASE_IBX	0x0180
66
#define	IMCSMB_REG_BASE_HSX	0x0180
67
#define	IMCSMB_REG_BASE_BDX	0x0180
68
#define	IMCSMB_REG_BASE_SLX	0x0e80
69
70
/* unit0: base; unit1: (base + 0x10) */
71
#define	IMCSMB_REG_STATUS(_b_, _u_)	((_b_) + ((_u_) * 0x10) + 0x00)
65
#define		IMCSMB_STATUS_BUSY_BIT		0x10000000
72
#define		IMCSMB_STATUS_BUSY_BIT		0x10000000
66
#define		IMCSMB_STATUS_BUS_ERROR_BIT	0x20000000
73
#define		IMCSMB_STATUS_BUS_ERROR_BIT	0x20000000
67
#define		IMCSMB_STATUS_WRITE_DATA_DONE	0x40000000
74
#define		IMCSMB_STATUS_WRITE_DATA_DONE	0x40000000
68
#define		IMCSMB_STATUS_READ_DATA_VALID	0x80000000
75
#define		IMCSMB_STATUS_READ_DATA_VALID	0x80000000
69
76
70
#define	IMCSMB_REG_COMMAND0			0x0184
77
/* unit0: (base + 0x04); unit1: (base + 0x14) */
71
#define	IMCSMB_REG_COMMAND1			0x0194
78
#define	IMCSMB_REG_COMMAND(_b_, _u_)	((_b_) + ((_u_) * 0x10) + 0x04)
72
#define		IMCSMB_CMD_WORD_ACCESS		0x20000000
79
#define		IMCSMB_CMD_WORD_ACCESS		0x20000000
73
#define		IMCSMB_CMD_WRITE_BIT		0x08000000
80
#define		IMCSMB_CMD_WRITE_BIT		0x08000000
74
#define		IMCSMB_CMD_TRIGGER_BIT		0x80000000
81
#define		IMCSMB_CMD_TRIGGER_BIT		0x80000000
75
82
76
#define	IMCSMB_REG_CONTROL0			0x0188
83
/* unit0: (base + 0x08); unit1: (base + 0x18) */
77
#define	IMCSMB_REG_CONTROL1			0x0198
84
#define	IMCSMB_REG_CONTROL(_b_, _u_)	((_b_) + ((_u_) * 0x10) + 0x08)
78
#define		IMCSMB_CNTL_POLL_EN		0x00000100
85
#define		IMCSMB_CNTL_POLL_EN		0x00000100
79
#define		IMCSMB_CNTL_CLK_OVERRIDE	0x08000000
86
#define		IMCSMB_CNTL_CLK_OVERRIDE	0x08000000
80
#define		IMCSMB_CNTL_DTI_MASK		0xf0000000
87
#define		IMCSMB_CNTL_DTI_MASK		0xf0000000

Return to bug 248514