msm_priv.h revision 7e102996
1/*
2 * Copyright (C) 2012-2018 Rob Clark <robclark@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Rob Clark <robclark@freedesktop.org>
25 */
26
27#ifndef MSM_PRIV_H_
28#define MSM_PRIV_H_
29
30#include "freedreno_priv.h"
31
32#ifndef __user
33#  define __user
34#endif
35
36#include "msm_drm.h"
37
38struct msm_device {
39	struct fd_device base;
40	struct fd_bo_cache ring_cache;
41};
42FD_DEFINE_CAST(fd_device, msm_device);
43
44struct fd_device * msm_device_new(int fd);
45
46struct msm_pipe {
47	struct fd_pipe base;
48	uint32_t pipe;
49	uint32_t gpu_id;
50	uint64_t gmem_base;
51	uint32_t gmem;
52	uint32_t chip_id;
53	uint32_t queue_id;
54};
55FD_DEFINE_CAST(fd_pipe, msm_pipe);
56
57struct fd_pipe * msm_pipe_new(struct fd_device *dev,
58		enum fd_pipe_id id, uint32_t prio);
59
60struct fd_ringbuffer * msm_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size);
61struct fd_ringbuffer * msm_ringbuffer_sp_new_object(struct fd_pipe *pipe, uint32_t size);
62
63struct fd_submit * msm_submit_new(struct fd_pipe *pipe);
64struct fd_submit * msm_submit_sp_new(struct fd_pipe *pipe);
65
66struct msm_bo {
67	struct fd_bo base;
68	uint64_t offset;
69	/* to avoid excess hashtable lookups, cache the ring this bo was
70	 * last emitted on (since that will probably also be the next ring
71	 * it is emitted on)
72	 */
73	unsigned current_submit_seqno;
74	uint32_t idx;
75};
76FD_DEFINE_CAST(fd_bo, msm_bo);
77
78int msm_bo_new_handle(struct fd_device *dev,
79		uint32_t size, uint32_t flags, uint32_t *handle);
80struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
81		uint32_t size, uint32_t handle);
82
83static inline void
84msm_dump_submit(struct drm_msm_gem_submit *req)
85{
86	for (unsigned i = 0; i < req->nr_bos; i++) {
87		struct drm_msm_gem_submit_bo *bos = U642VOID(req->bos);
88		struct drm_msm_gem_submit_bo *bo = &bos[i];
89		ERROR_MSG("  bos[%d]: handle=%u, flags=%x", i, bo->handle, bo->flags);
90	}
91	for (unsigned i = 0; i < req->nr_cmds; i++) {
92		struct drm_msm_gem_submit_cmd *cmds = U642VOID(req->cmds);
93		struct drm_msm_gem_submit_cmd *cmd = &cmds[i];
94		struct drm_msm_gem_submit_reloc *relocs = U642VOID(cmd->relocs);
95		ERROR_MSG("  cmd[%d]: type=%u, submit_idx=%u, submit_offset=%u, size=%u",
96				i, cmd->type, cmd->submit_idx, cmd->submit_offset, cmd->size);
97		for (unsigned j = 0; j < cmd->nr_relocs; j++) {
98			struct drm_msm_gem_submit_reloc *r = &relocs[j];
99			ERROR_MSG("    reloc[%d]: submit_offset=%u, or=%08x, shift=%d, reloc_idx=%u"
100					", reloc_offset=%"PRIu64, j, r->submit_offset, r->or, r->shift,
101					r->reloc_idx, r->reloc_offset);
102		}
103	}
104}
105
106static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns)
107{
108	struct timespec t;
109	uint32_t s = ns / 1000000000;
110	clock_gettime(CLOCK_MONOTONIC, &t);
111	tv->tv_sec = t.tv_sec + s;
112	tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000);
113}
114
115/*
116 * Stupid/simple growable array implementation:
117 */
118
119static inline void *
120grow(void *ptr, uint16_t nr, uint16_t *max, uint16_t sz)
121{
122	if ((nr + 1) > *max) {
123		if ((*max * 2) < (nr + 1))
124			*max = nr + 5;
125		else
126			*max = *max * 2;
127		ptr = realloc(ptr, *max * sz);
128	}
129	return ptr;
130}
131
132#define DECLARE_ARRAY(type, name) \
133	unsigned short nr_ ## name, max_ ## name; \
134	type * name;
135
136#define APPEND(x, name) ({ \
137	(x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \
138	(x)->nr_ ## name ++; \
139})
140
141#endif /* MSM_PRIV_H_ */
142