sp-pci.c 7.7 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
 * AMD Secure Processor device driver
4
 *
5
 * Copyright (C) 2013,2019 Advanced Micro Devices, Inc.
6 7
 *
 * Author: Tom Lendacky <thomas.lendacky@amd.com>
8
 * Author: Gary R Hook <gary.hook@amd.com>
9 10 11 12
 */

#include <linux/module.h>
#include <linux/kernel.h>
13
#include <linux/device.h>
14 15
#include <linux/pci.h>
#include <linux/pci_ids.h>
16
#include <linux/dma-mapping.h>
17 18 19 20 21 22 23 24
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/ccp.h>

#include "ccp-dev.h"
25
#include "psp-dev.h"
26 27 28

#define MSIX_VECTORS			2

29
struct sp_pci {
30
	int msix_count;
31
	struct msix_entry msix_entry[MSIX_VECTORS];
32
};
33
static struct sp_device *sp_dev_master;
34

35
static int sp_get_msix_irqs(struct sp_device *sp)
36
{
37
	struct sp_pci *sp_pci = sp->dev_specific;
38
	struct device *dev = sp->dev;
39
	struct pci_dev *pdev = to_pci_dev(dev);
40 41
	int v, ret;

42 43
	for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++)
		sp_pci->msix_entry[v].entry = v;
44

45
	ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v);
46
	if (ret < 0)
47 48
		return ret;

49
	sp_pci->msix_count = ret;
50
	sp->use_tasklet = true;
51

52 53 54
	sp->psp_irq = sp_pci->msix_entry[0].vector;
	sp->ccp_irq = (sp_pci->msix_count > 1) ? sp_pci->msix_entry[1].vector
					       : sp_pci->msix_entry[0].vector;
55 56 57
	return 0;
}

58
static int sp_get_msi_irq(struct sp_device *sp)
59
{
60
	struct device *dev = sp->dev;
61
	struct pci_dev *pdev = to_pci_dev(dev);
62 63 64 65 66 67
	int ret;

	ret = pci_enable_msi(pdev);
	if (ret)
		return ret;

68 69
	sp->ccp_irq = pdev->irq;
	sp->psp_irq = pdev->irq;
70 71 72 73

	return 0;
}

74
static int sp_get_irqs(struct sp_device *sp)
75
{
76
	struct device *dev = sp->dev;
77 78
	int ret;

79
	ret = sp_get_msix_irqs(sp);
80 81 82 83 84
	if (!ret)
		return 0;

	/* Couldn't get MSI-X vectors, try MSI */
	dev_notice(dev, "could not enable MSI-X (%d), trying MSI\n", ret);
85
	ret = sp_get_msi_irq(sp);
86 87 88 89 90 91 92 93 94
	if (!ret)
		return 0;

	/* Couldn't get MSI interrupt */
	dev_notice(dev, "could not enable MSI (%d)\n", ret);

	return ret;
}

95
static void sp_free_irqs(struct sp_device *sp)
96
{
97
	struct sp_pci *sp_pci = sp->dev_specific;
98
	struct device *dev = sp->dev;
99
	struct pci_dev *pdev = to_pci_dev(dev);
100

101
	if (sp_pci->msix_count)
102
		pci_disable_msix(pdev);
103
	else if (sp->psp_irq)
104
		pci_disable_msi(pdev);
105 106 107

	sp->ccp_irq = 0;
	sp->psp_irq = 0;
108 109
}

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
static bool sp_pci_is_master(struct sp_device *sp)
{
	struct device *dev_cur, *dev_new;
	struct pci_dev *pdev_cur, *pdev_new;

	dev_new = sp->dev;
	dev_cur = sp_dev_master->dev;

	pdev_new = to_pci_dev(dev_new);
	pdev_cur = to_pci_dev(dev_cur);

	if (pdev_new->bus->number < pdev_cur->bus->number)
		return true;

	if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn))
		return true;

	if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn))
		return true;

	return false;
}

static void psp_set_master(struct sp_device *sp)
{
	if (!sp_dev_master) {
		sp_dev_master = sp;
		return;
	}

	if (sp_pci_is_master(sp))
		sp_dev_master = sp;
}

static struct sp_device *psp_get_master(void)
{
	return sp_dev_master;
}

149 150 151 152 153 154 155 156
static void psp_clear_master(struct sp_device *sp)
{
	if (sp == sp_dev_master) {
		sp_dev_master = NULL;
		dev_dbg(sp->dev, "Cleared sp_dev_master\n");
	}
}

157
static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
158
{
159
	struct sp_device *sp;
160
	struct sp_pci *sp_pci;
161
	struct device *dev = &pdev->dev;
162 163
	void __iomem * const *iomap_table;
	int bar_mask;
164 165 166
	int ret;

	ret = -ENOMEM;
167 168
	sp = sp_alloc_struct(dev);
	if (!sp)
169 170
		goto e_err;

171 172
	sp_pci = devm_kzalloc(dev, sizeof(*sp_pci), GFP_KERNEL);
	if (!sp_pci)
173 174
		goto e_err;

175
	sp->dev_specific = sp_pci;
176 177
	sp->dev_vdata = (struct sp_dev_vdata *)id->driver_data;
	if (!sp->dev_vdata) {
178 179 180 181
		ret = -ENODEV;
		dev_err(dev, "missing driver data\n");
		goto e_err;
	}
182

183
	ret = pcim_enable_device(pdev);
184
	if (ret) {
185
		dev_err(dev, "pcim_enable_device failed (%d)\n", ret);
186
		goto e_err;
187 188
	}

189 190
	bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
	ret = pcim_iomap_regions(pdev, bar_mask, "ccp");
191
	if (ret) {
192 193
		dev_err(dev, "pcim_iomap_regions failed (%d)\n", ret);
		goto e_err;
194 195
	}

196 197 198 199 200 201
	iomap_table = pcim_iomap_table(pdev);
	if (!iomap_table) {
		dev_err(dev, "pcim_iomap_table failed\n");
		ret = -ENOMEM;
		goto e_err;
	}
202

203 204
	sp->io_map = iomap_table[sp->dev_vdata->bar];
	if (!sp->io_map) {
205 206 207
		dev_err(dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto e_err;
208
	}
209

210
	ret = sp_get_irqs(sp);
211 212 213
	if (ret)
		goto e_err;

214
	pci_set_master(pdev);
215 216
	sp->set_psp_master_device = psp_set_master;
	sp->get_psp_master_device = psp_get_master;
217
	sp->clear_psp_master_device = psp_clear_master;
218

219 220 221
	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
	if (ret) {
		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
222
		if (ret) {
223
			dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
224
				ret);
225
			goto free_irqs;
226 227 228
		}
	}

229
	dev_set_drvdata(dev, sp);
230

231
	ret = sp_init(sp);
232
	if (ret)
233
		goto free_irqs;
234 235 236

	return 0;

237 238
free_irqs:
	sp_free_irqs(sp);
239 240 241 242 243
e_err:
	dev_notice(dev, "initialization failed\n");
	return ret;
}

244
static void sp_pci_remove(struct pci_dev *pdev)
245 246
{
	struct device *dev = &pdev->dev;
247
	struct sp_device *sp = dev_get_drvdata(dev);
248

249
	if (!sp)
250 251
		return;

252
	sp_destroy(sp);
253

254
	sp_free_irqs(sp);
255 256
}

257
static int __maybe_unused sp_pci_suspend(struct device *dev)
258
{
259
	struct sp_device *sp = dev_get_drvdata(dev);
260

261
	return sp_suspend(sp);
262 263
}

264
static int __maybe_unused sp_pci_resume(struct device *dev)
265
{
266
	struct sp_device *sp = dev_get_drvdata(dev);
267

268
	return sp_resume(sp);
269 270
}

271
#ifdef CONFIG_CRYPTO_DEV_SP_PSP
272
static const struct sev_vdata sevv1 = {
273 274 275
	.cmdresp_reg		= 0x10580,
	.cmdbuff_addr_lo_reg	= 0x105e0,
	.cmdbuff_addr_hi_reg	= 0x105e4,
276 277 278 279 280 281 282 283
};

static const struct sev_vdata sevv2 = {
	.cmdresp_reg		= 0x10980,
	.cmdbuff_addr_lo_reg	= 0x109e0,
	.cmdbuff_addr_hi_reg	= 0x109e4,
};

284 285 286 287 288 289 290 291
static const struct tee_vdata teev1 = {
	.cmdresp_reg		= 0x10544,
	.cmdbuff_addr_lo_reg	= 0x10548,
	.cmdbuff_addr_hi_reg	= 0x1054c,
	.ring_wptr_reg          = 0x10550,
	.ring_rptr_reg          = 0x10554,
};

292 293
static const struct psp_vdata pspv1 = {
	.sev			= &sevv1,
294 295 296
	.feature_reg		= 0x105fc,
	.inten_reg		= 0x10610,
	.intsts_reg		= 0x10614,
297
};
298 299

static const struct psp_vdata pspv2 = {
300
	.sev			= &sevv2,
301 302 303 304
	.feature_reg		= 0x109fc,
	.inten_reg		= 0x10690,
	.intsts_reg		= 0x10694,
};
305 306 307 308 309 310 311

static const struct psp_vdata pspv3 = {
	.tee			= &teev1,
	.feature_reg		= 0x109fc,
	.inten_reg		= 0x10690,
	.intsts_reg		= 0x10694,
};
312 313
#endif

314
static const struct sp_dev_vdata dev_vdata[] = {
315
	{	/* 0 */
316 317 318 319 320
		.bar = 2,
#ifdef CONFIG_CRYPTO_DEV_SP_CCP
		.ccp_vdata = &ccpv3,
#endif
	},
321
	{	/* 1 */
322 323 324
		.bar = 2,
#ifdef CONFIG_CRYPTO_DEV_SP_CCP
		.ccp_vdata = &ccpv5a,
325 326
#endif
#ifdef CONFIG_CRYPTO_DEV_SP_PSP
327
		.psp_vdata = &pspv1,
328 329
#endif
	},
330
	{	/* 2 */
331 332 333
		.bar = 2,
#ifdef CONFIG_CRYPTO_DEV_SP_CCP
		.ccp_vdata = &ccpv5b,
334 335 336 337 338 339 340 341 342
#endif
	},
	{	/* 3 */
		.bar = 2,
#ifdef CONFIG_CRYPTO_DEV_SP_CCP
		.ccp_vdata = &ccpv5a,
#endif
#ifdef CONFIG_CRYPTO_DEV_SP_PSP
		.psp_vdata = &pspv2,
343 344 345 346 347 348 349 350 351
#endif
	},
	{	/* 4 */
		.bar = 2,
#ifdef CONFIG_CRYPTO_DEV_SP_CCP
		.ccp_vdata = &ccpv5a,
#endif
#ifdef CONFIG_CRYPTO_DEV_SP_PSP
		.psp_vdata = &pspv3,
352 353 354
#endif
	},
};
355
static const struct pci_device_id sp_pci_table[] = {
356 357 358
	{ PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] },
	{ PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] },
	{ PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
359
	{ PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] },
360
	{ PCI_VDEVICE(AMD, 0x15DF), (kernel_ulong_t)&dev_vdata[4] },
361 362 363
	/* Last entry must be zero */
	{ 0, }
};
364
MODULE_DEVICE_TABLE(pci, sp_pci_table);
365

366 367
static SIMPLE_DEV_PM_OPS(sp_pci_pm_ops, sp_pci_suspend, sp_pci_resume);

368
static struct pci_driver sp_pci_driver = {
369
	.name = "ccp",
370 371 372
	.id_table = sp_pci_table,
	.probe = sp_pci_probe,
	.remove = sp_pci_remove,
373
	.driver.pm = &sp_pci_pm_ops,
374 375
};

376
int sp_pci_init(void)
377
{
378
	return pci_register_driver(&sp_pci_driver);
379 380
}

381
void sp_pci_exit(void)
382
{
383
	pci_unregister_driver(&sp_pci_driver);
384
}