summaryrefslogtreecommitdiff
path: root/drivers/crypto/ccp/sp-dev.h
blob: 0218d0670eeefdf274f0a9a2d45aac0491b1d385 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * AMD Secure Processor driver
 *
 * Copyright (C) 2017-2019 Advanced Micro Devices, Inc.
 *
 * Author: Tom Lendacky <thomas.lendacky@amd.com>
 * Author: Gary R Hook <gary.hook@amd.com>
 * Author: Brijesh Singh <brijesh.singh@amd.com>
 */

#ifndef __SP_DEV_H__
#define __SP_DEV_H__

#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/dmapool.h>
#include <linux/hw_random.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>

#define SP_MAX_NAME_LEN		32

#define CACHE_NONE			0x00
#define CACHE_WB_NO_ALLOC		0xb7

/* Structure to hold CCP device data */
struct ccp_device;
struct ccp_vdata {
	const unsigned int version;
	const unsigned int dma_chan_attr;
	void (*setup)(struct ccp_device *);
	const struct ccp_actions *perform;
	const unsigned int offset;
	const unsigned int rsamax;
};

struct sev_vdata {
	const unsigned int cmdresp_reg;
	const unsigned int cmdbuff_addr_lo_reg;
	const unsigned int cmdbuff_addr_hi_reg;
};

struct tee_vdata {
	const unsigned int cmdresp_reg;
	const unsigned int cmdbuff_addr_lo_reg;
	const unsigned int cmdbuff_addr_hi_reg;
	const unsigned int ring_wptr_reg;
	const unsigned int ring_rptr_reg;
};

struct psp_vdata {
	const struct sev_vdata *sev;
	const struct tee_vdata *tee;
	const unsigned int feature_reg;
	const unsigned int inten_reg;
	const unsigned int intsts_reg;
};

/* Structure to hold SP device data */
struct sp_dev_vdata {
	const unsigned int bar;

	const struct ccp_vdata *ccp_vdata;
	const struct psp_vdata *psp_vdata;
};

struct sp_device {
	struct list_head entry;

	struct device *dev;

	struct sp_dev_vdata *dev_vdata;
	unsigned int ord;
	char name[SP_MAX_NAME_LEN];

	/* Bus specific device information */
	void *dev_specific;

	/* I/O area used for device communication. */
	void __iomem *io_map;

	/* DMA caching attribute support */
	unsigned int axcache;

	/* get and set master device */
	struct sp_device*(*get_psp_master_device)(void);
	void (*set_psp_master_device)(struct sp_device *);
	void (*clear_psp_master_device)(struct sp_device *);

	bool irq_registered;
	bool use_tasklet;

	unsigned int ccp_irq;
	irq_handler_t ccp_irq_handler;
	void *ccp_irq_data;

	unsigned int psp_irq;
	irq_handler_t psp_irq_handler;
	void *psp_irq_data;

	void *ccp_data;
	void *psp_data;
};

int sp_pci_init(void);
void sp_pci_exit(void);

int sp_platform_init(void);
void sp_platform_exit(void);

struct sp_device *sp_alloc_struct(struct device *dev);

int sp_init(struct sp_device *sp);
void sp_destroy(struct sp_device *sp);
struct sp_device *sp_get_master(void);

int sp_suspend(struct sp_device *sp);
int sp_resume(struct sp_device *sp);
int sp_request_ccp_irq(struct sp_device *sp, irq_handler_t handler,
		       const char *name, void *data);
void sp_free_ccp_irq(struct sp_device *sp, void *data);
int sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler,
		       const char *name, void *data);
void sp_free_psp_irq(struct sp_device *sp, void *data);
struct sp_device *sp_get_psp_master_device(void);

#ifdef CONFIG_CRYPTO_DEV_SP_CCP

int ccp_dev_init(struct sp_device *sp);
void ccp_dev_destroy(struct sp_device *sp);

int ccp_dev_suspend(struct sp_device *sp);
int ccp_dev_resume(struct sp_device *sp);

#else	/* !CONFIG_CRYPTO_DEV_SP_CCP */

static inline int ccp_dev_init(struct sp_device *sp)
{
	return 0;
}
static inline void ccp_dev_destroy(struct sp_device *sp) { }

static inline int ccp_dev_suspend(struct sp_device *sp)
{
	return 0;
}
static inline int ccp_dev_resume(struct sp_device *sp)
{
	return 0;
}
#endif	/* CONFIG_CRYPTO_DEV_SP_CCP */

#ifdef CONFIG_CRYPTO_DEV_SP_PSP

int psp_dev_init(struct sp_device *sp);
void psp_pci_init(void);
void psp_dev_destroy(struct sp_device *sp);
void psp_pci_exit(void);

#else /* !CONFIG_CRYPTO_DEV_SP_PSP */

static inline int psp_dev_init(struct sp_device *sp) { return 0; }
static inline void psp_pci_init(void) { }
static inline void psp_dev_destroy(struct sp_device *sp) { }
static inline void psp_pci_exit(void) { }

#endif /* CONFIG_CRYPTO_DEV_SP_PSP */

#endif