import OT_8063_20170412 mali driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / common / mali_timeline_sync_fence.c
CommitLineData
6fa3eb70
S
1/*
2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
bdc132d7 4 * (C) COPYRIGHT 2013, 2015 ARM Limited
6fa3eb70
S
5 * ALL RIGHTS RESERVED
6 * The entire notice above must be reproduced on all authorised
7 * copies and copies may only be made to the extent permitted
8 * by a licensing agreement from ARM Limited.
9 */
10
11#include "mali_timeline_sync_fence.h"
12
13#include "mali_osk.h"
14#include "mali_kernel_common.h"
15#include "mali_sync.h"
16
17#if defined(CONFIG_SYNC)
18
19/**
20 * Creates a sync fence tracker and a sync fence. Adds sync fence tracker to Timeline system and
21 * returns sync fence. The sync fence will be signaled when the sync fence tracker is activated.
22 *
23 * @param timeline Timeline.
24 * @param point Point on timeline.
25 * @return Sync fence that will be signaled when tracker is activated.
26 */
27static struct sync_fence *mali_timeline_sync_fence_create_and_add_tracker(struct mali_timeline *timeline, mali_timeline_point point)
28{
29 struct mali_timeline_sync_fence_tracker *sync_fence_tracker;
30 struct sync_fence *sync_fence;
31 struct mali_timeline_fence fence;
32
33 MALI_DEBUG_ASSERT_POINTER(timeline);
34 MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT != point);
35
36 /* Allocate sync fence tracker. */
37 sync_fence_tracker = _mali_osk_calloc(1, sizeof(struct mali_timeline_sync_fence_tracker));
38 if (NULL == sync_fence_tracker) {
39 MALI_PRINT_ERROR(("Mali Timeline: sync_fence_tracker allocation failed\n"));
40 return NULL;
41 }
42
43 /* Create sync flag. */
44 MALI_DEBUG_ASSERT_POINTER(timeline->sync_tl);
45 sync_fence_tracker->flag = mali_sync_flag_create(timeline->sync_tl, point);
46 if (NULL == sync_fence_tracker->flag) {
47 MALI_PRINT_ERROR(("Mali Timeline: sync_flag creation failed\n"));
48 _mali_osk_free(sync_fence_tracker);
49 return NULL;
50 }
51
52 /* Create sync fence from sync flag. */
53 sync_fence = mali_sync_flag_create_fence(sync_fence_tracker->flag);
54 if (NULL == sync_fence) {
55 MALI_PRINT_ERROR(("Mali Timeline: sync_fence creation failed\n"));
56 mali_sync_flag_put(sync_fence_tracker->flag);
57 _mali_osk_free(sync_fence_tracker);
58 return NULL;
59 }
60
61 /* Setup fence for tracker. */
62 _mali_osk_memset(&fence, 0, sizeof(struct mali_timeline_fence));
63 fence.sync_fd = -1;
64 fence.points[timeline->id] = point;
65
66 /* Finally, add the tracker to Timeline system. */
67 mali_timeline_tracker_init(&sync_fence_tracker->tracker, MALI_TIMELINE_TRACKER_SYNC, &fence, sync_fence_tracker);
68 point = mali_timeline_system_add_tracker(timeline->system, &sync_fence_tracker->tracker, MALI_TIMELINE_NONE);
69 MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT == point);
70
71 return sync_fence;
72}
73
74s32 mali_timeline_sync_fence_create(struct mali_timeline_system *system, struct mali_timeline_fence *fence)
75{
76 u32 i;
77 struct sync_fence *sync_fence_acc = NULL;
78
79 MALI_DEBUG_ASSERT_POINTER(system);
80 MALI_DEBUG_ASSERT_POINTER(fence);
81
82 for (i = 0; i < MALI_TIMELINE_MAX; ++i) {
83 struct mali_timeline *timeline;
84 struct sync_fence *sync_fence;
85
86 if (MALI_TIMELINE_NO_POINT == fence->points[i]) continue;
87
88 timeline = system->timelines[i];
89 MALI_DEBUG_ASSERT_POINTER(timeline);
90
91 sync_fence = mali_timeline_sync_fence_create_and_add_tracker(timeline, fence->points[i]);
bdc132d7
S
92 if (NULL == sync_fence) goto error;
93
6fa3eb70
S
94 if (NULL != sync_fence_acc) {
95 /* Merge sync fences. */
96 sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence);
bdc132d7 97 if (NULL == sync_fence_acc) goto error;
6fa3eb70
S
98 } else {
99 /* This was the first sync fence created. */
100 sync_fence_acc = sync_fence;
101 }
102 }
103
104 if (-1 != fence->sync_fd) {
105 struct sync_fence *sync_fence;
106
107 sync_fence = sync_fence_fdget(fence->sync_fd);
bdc132d7
S
108 if (NULL == sync_fence) goto error;
109
6fa3eb70
S
110 if (NULL != sync_fence_acc) {
111 sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence);
bdc132d7 112 if (NULL == sync_fence_acc) goto error;
6fa3eb70
S
113 } else {
114 sync_fence_acc = sync_fence;
115 }
116 }
117
118 if (NULL == sync_fence_acc) {
119 MALI_DEBUG_ASSERT_POINTER(system->signaled_sync_tl);
120
121 /* There was nothing to wait on, so return an already signaled fence. */
122
123 sync_fence_acc = mali_sync_timeline_create_signaled_fence(system->signaled_sync_tl);
bdc132d7 124 if (NULL == sync_fence_acc) goto error;
6fa3eb70
S
125 }
126
127 /* Return file descriptor for the accumulated sync fence. */
128 return mali_sync_fence_fd_alloc(sync_fence_acc);
129
130error:
131 if (NULL != sync_fence_acc) {
132 sync_fence_put(sync_fence_acc);
133 }
bdc132d7 134
6fa3eb70
S
135 return -1;
136}
137
138void mali_timeline_sync_fence_activate(struct mali_timeline_sync_fence_tracker *sync_fence_tracker)
139{
140 mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;
141
142 MALI_DEBUG_ASSERT_POINTER(sync_fence_tracker);
143 MALI_DEBUG_ASSERT_POINTER(sync_fence_tracker->flag);
144
145 MALI_DEBUG_PRINT(4, ("Mali Timeline: activation for sync fence tracker\n"));
146
147 /* Signal flag and release reference. */
148 mali_sync_flag_signal(sync_fence_tracker->flag, 0);
149 mali_sync_flag_put(sync_fence_tracker->flag);
150
151 /* Nothing can wait on this tracker, so nothing to schedule after release. */
152 schedule_mask = mali_timeline_tracker_release(&sync_fence_tracker->tracker);
153 MALI_DEBUG_ASSERT(MALI_SCHEDULER_MASK_EMPTY == schedule_mask);
154
155 _mali_osk_free(sync_fence_tracker);
156}
157
158#endif /* defined(CONFIG_SYNC) */