18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * AMD Secure Processor driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2017-2019 Advanced Micro Devices, Inc.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Author: Tom Lendacky <thomas.lendacky@amd.com>
88c2ecf20Sopenharmony_ci * Author: Gary R Hook <gary.hook@amd.com>
98c2ecf20Sopenharmony_ci * Author: Brijesh Singh <brijesh.singh@amd.com>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#ifndef __SP_DEV_H__
138c2ecf20Sopenharmony_ci#define __SP_DEV_H__
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/device.h>
168c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
178c2ecf20Sopenharmony_ci#include <linux/mutex.h>
188c2ecf20Sopenharmony_ci#include <linux/list.h>
198c2ecf20Sopenharmony_ci#include <linux/wait.h>
208c2ecf20Sopenharmony_ci#include <linux/dmapool.h>
218c2ecf20Sopenharmony_ci#include <linux/hw_random.h>
228c2ecf20Sopenharmony_ci#include <linux/bitops.h>
238c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
248c2ecf20Sopenharmony_ci#include <linux/irqreturn.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define SP_MAX_NAME_LEN		32
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#define CACHE_NONE			0x00
298c2ecf20Sopenharmony_ci#define CACHE_WB_NO_ALLOC		0xb7
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* Structure to hold CCP device data */
328c2ecf20Sopenharmony_cistruct ccp_device;
338c2ecf20Sopenharmony_cistruct ccp_vdata {
348c2ecf20Sopenharmony_ci	const unsigned int version;
358c2ecf20Sopenharmony_ci	const unsigned int dma_chan_attr;
368c2ecf20Sopenharmony_ci	void (*setup)(struct ccp_device *);
378c2ecf20Sopenharmony_ci	const struct ccp_actions *perform;
388c2ecf20Sopenharmony_ci	const unsigned int offset;
398c2ecf20Sopenharmony_ci	const unsigned int rsamax;
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistruct sev_vdata {
438c2ecf20Sopenharmony_ci	const unsigned int cmdresp_reg;
448c2ecf20Sopenharmony_ci	const unsigned int cmdbuff_addr_lo_reg;
458c2ecf20Sopenharmony_ci	const unsigned int cmdbuff_addr_hi_reg;
468c2ecf20Sopenharmony_ci};
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistruct tee_vdata {
498c2ecf20Sopenharmony_ci	const unsigned int cmdresp_reg;
508c2ecf20Sopenharmony_ci	const unsigned int cmdbuff_addr_lo_reg;
518c2ecf20Sopenharmony_ci	const unsigned int cmdbuff_addr_hi_reg;
528c2ecf20Sopenharmony_ci	const unsigned int ring_wptr_reg;
538c2ecf20Sopenharmony_ci	const unsigned int ring_rptr_reg;
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistruct psp_vdata {
578c2ecf20Sopenharmony_ci	const struct sev_vdata *sev;
588c2ecf20Sopenharmony_ci	const struct tee_vdata *tee;
598c2ecf20Sopenharmony_ci	const unsigned int feature_reg;
608c2ecf20Sopenharmony_ci	const unsigned int inten_reg;
618c2ecf20Sopenharmony_ci	const unsigned int intsts_reg;
628c2ecf20Sopenharmony_ci};
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/* Structure to hold SP device data */
658c2ecf20Sopenharmony_cistruct sp_dev_vdata {
668c2ecf20Sopenharmony_ci	const unsigned int bar;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	const struct ccp_vdata *ccp_vdata;
698c2ecf20Sopenharmony_ci	const struct psp_vdata *psp_vdata;
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistruct sp_device {
738c2ecf20Sopenharmony_ci	struct list_head entry;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	struct device *dev;
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	struct sp_dev_vdata *dev_vdata;
788c2ecf20Sopenharmony_ci	unsigned int ord;
798c2ecf20Sopenharmony_ci	char name[SP_MAX_NAME_LEN];
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	/* Bus specific device information */
828c2ecf20Sopenharmony_ci	void *dev_specific;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	/* I/O area used for device communication. */
858c2ecf20Sopenharmony_ci	void __iomem *io_map;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	/* DMA caching attribute support */
888c2ecf20Sopenharmony_ci	unsigned int axcache;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	/* get and set master device */
918c2ecf20Sopenharmony_ci	struct sp_device*(*get_psp_master_device)(void);
928c2ecf20Sopenharmony_ci	void (*set_psp_master_device)(struct sp_device *);
938c2ecf20Sopenharmony_ci	void (*clear_psp_master_device)(struct sp_device *);
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	bool irq_registered;
968c2ecf20Sopenharmony_ci	bool use_tasklet;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	unsigned int ccp_irq;
998c2ecf20Sopenharmony_ci	irq_handler_t ccp_irq_handler;
1008c2ecf20Sopenharmony_ci	void *ccp_irq_data;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	unsigned int psp_irq;
1038c2ecf20Sopenharmony_ci	irq_handler_t psp_irq_handler;
1048c2ecf20Sopenharmony_ci	void *psp_irq_data;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	void *ccp_data;
1078c2ecf20Sopenharmony_ci	void *psp_data;
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ciint sp_pci_init(void);
1118c2ecf20Sopenharmony_civoid sp_pci_exit(void);
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ciint sp_platform_init(void);
1148c2ecf20Sopenharmony_civoid sp_platform_exit(void);
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistruct sp_device *sp_alloc_struct(struct device *dev);
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ciint sp_init(struct sp_device *sp);
1198c2ecf20Sopenharmony_civoid sp_destroy(struct sp_device *sp);
1208c2ecf20Sopenharmony_cistruct sp_device *sp_get_master(void);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ciint sp_suspend(struct sp_device *sp);
1238c2ecf20Sopenharmony_ciint sp_resume(struct sp_device *sp);
1248c2ecf20Sopenharmony_ciint sp_request_ccp_irq(struct sp_device *sp, irq_handler_t handler,
1258c2ecf20Sopenharmony_ci		       const char *name, void *data);
1268c2ecf20Sopenharmony_civoid sp_free_ccp_irq(struct sp_device *sp, void *data);
1278c2ecf20Sopenharmony_ciint sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler,
1288c2ecf20Sopenharmony_ci		       const char *name, void *data);
1298c2ecf20Sopenharmony_civoid sp_free_psp_irq(struct sp_device *sp, void *data);
1308c2ecf20Sopenharmony_cistruct sp_device *sp_get_psp_master_device(void);
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_CCP
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ciint ccp_dev_init(struct sp_device *sp);
1358c2ecf20Sopenharmony_civoid ccp_dev_destroy(struct sp_device *sp);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciint ccp_dev_suspend(struct sp_device *sp);
1388c2ecf20Sopenharmony_ciint ccp_dev_resume(struct sp_device *sp);
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci#else	/* !CONFIG_CRYPTO_DEV_SP_CCP */
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_cistatic inline int ccp_dev_init(struct sp_device *sp)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	return 0;
1458c2ecf20Sopenharmony_ci}
1468c2ecf20Sopenharmony_cistatic inline void ccp_dev_destroy(struct sp_device *sp) { }
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic inline int ccp_dev_suspend(struct sp_device *sp)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	return 0;
1518c2ecf20Sopenharmony_ci}
1528c2ecf20Sopenharmony_cistatic inline int ccp_dev_resume(struct sp_device *sp)
1538c2ecf20Sopenharmony_ci{
1548c2ecf20Sopenharmony_ci	return 0;
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci#endif	/* CONFIG_CRYPTO_DEV_SP_CCP */
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_PSP
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ciint psp_dev_init(struct sp_device *sp);
1618c2ecf20Sopenharmony_civoid psp_pci_init(void);
1628c2ecf20Sopenharmony_civoid psp_dev_destroy(struct sp_device *sp);
1638c2ecf20Sopenharmony_civoid psp_pci_exit(void);
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci#else /* !CONFIG_CRYPTO_DEV_SP_PSP */
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic inline int psp_dev_init(struct sp_device *sp) { return 0; }
1688c2ecf20Sopenharmony_cistatic inline void psp_pci_init(void) { }
1698c2ecf20Sopenharmony_cistatic inline void psp_dev_destroy(struct sp_device *sp) { }
1708c2ecf20Sopenharmony_cistatic inline void psp_pci_exit(void) { }
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci#endif /* CONFIG_CRYPTO_DEV_SP_PSP */
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci#endif
175