blob: 2193d77d4ebb911ec26cdba364e4c5b413501292 (
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
|
/* SPDX-License-Identifier: GPL-2.0 */
/*
* GXP virtual device manager.
*
* Copyright (C) 2021 Google LLC
*/
#ifndef __GXP_VD_H__
#define __GXP_VD_H__
#include <linux/iommu.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
#include "gxp-internal.h"
struct mailbox_resp_queue {
/* Queue of `struct gxp_async_response`s */
struct list_head queue;
/* Lock protecting access to the `queue` */
spinlock_t lock;
/* Waitqueue to wait on if the queue is empty */
wait_queue_head_t waitq;
};
struct gxp_virtual_device {
struct gxp_dev *gxp;
uint num_cores;
void *fw_app;
struct iommu_domain **core_domains;
struct mailbox_resp_queue *mailbox_resp_queues;
};
/*
* TODO(b/193180931) cleanup the relationship between the internal GXP modules.
* For example, whether or not gxp_vd owns the gxp_fw module, and if so, if
* other modules are expected to access the gxp_fw directly or only via gxp_vd.
*/
/*
* Initializes the device management subsystem and allocates resources for it.
* This is expected to be called once per driver lifecycle.
*/
int gxp_vd_init(struct gxp_dev *gxp);
/*
* Tears down the device management subsystem.
* This is expected to be called once per driver lifecycle.
*/
void gxp_vd_destroy(struct gxp_dev *gxp);
/**
* gxp_vd_allocate() - Allocate and initialize a struct gxp_virtual_device
* @gxp: The GXP device the virtual device will belong to
* @requested_cores: The number of cores the virtual device will have
*
* Return: The virtual address of the virtual device or an ERR_PTR on failure
* * -EINVAL - The number of requested cores was invalid
* * -ENOMEM - Unable to allocate the virtual device
*/
struct gxp_virtual_device *gxp_vd_allocate(struct gxp_dev *gxp, u16 requested_cores);
/**
* gxp_vd_release() - Cleanup and free a struct gxp_virtual_device
* @vd: The virtual device to be released
*
* A virtual device must be stopped before it can be released.
*/
void gxp_vd_release(struct gxp_virtual_device *vd);
/**
* gxp_vd_start() - Run a virtual device on physical cores
* @vd: The virtual device to start
*
* The caller must have locked gxp->vd_semaphore for writing.
*
* Return:
* * 0 - Success
* * -EBUSY - Insufficient physical cores were free to start @vd
*/
int gxp_vd_start(struct gxp_virtual_device *vd);
/**
* gxp_vd_stop() - Stop a running virtual device and free up physical cores
* @vd: The virtual device to stop
*
* The caller must have locked gxp->vd_semaphore for writing.
*/
void gxp_vd_stop(struct gxp_virtual_device *vd);
/*
* Returns the physical core ID for the specified virtual_core belonging to
* this virtual device or -EINVAL if this virtual core is not running on a
* physical core.
*
* The caller must have locked gxp->vd_semaphore for reading.
*/
int gxp_vd_virt_core_to_phys_core(struct gxp_virtual_device *vd, u16 virt_core);
/*
* Converts a bitfield of virtual core IDs to a bitfield of physical core IDs.
*
* If the virtual list contains any invalid IDs, the entire physical ID list
* will be considered invalid and this function will return 0.
*
* The caller must have locked gxp->vd_semaphore for reading.
*/
uint gxp_vd_virt_core_list_to_phys_core_list(struct gxp_virtual_device *vd,
u16 virt_core_list);
/*
* Returns the virtual core number assigned the phys_core, inside of this
* virtual device or -EINVAL if this core is not part of this virtual device.
*
* The caller must have locked gxp->vd_semaphore for reading.
*/
int gxp_vd_phys_core_to_virt_core(struct gxp_virtual_device *vd, u16 phys_core);
#endif /* __GXP_VD_H__ */
|