• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include "drm_hal_gfx.h"
20 #include <linux/module.h>
21 #include "hifb_vou_drv.h"
22 #include "hifb_vou_graphics.h"
23 #include "hifb_main.h"
24 #include "hi_drm_func_ext.h"
25 
26 #define hal_gfx_check_open(layer_param) do {     \
27     if (layer_param == NULL || layer_param->open_cnt <= 0) { \
28         drm_hal_err("layer not opened!\n"); \
29         return -1; \
30     } \
31 } while (0)
32 
33 #define hal_gfx_check_ptr(ptr) do {     \
34     if (ptr == NULL) { \
35         drm_hal_err("null ptr!\n"); \
36         return -1; \
37     } \
38 } while (0)
39 
40 struct gfx_layer_params {
41     unsigned int layer_id;
42     int open_cnt;
43     drm_hal_gfx_cb gfx_cb;
44 };
45 
46 struct hal_gfx_dev_params {
47     hifb_drv_ops gfx_api;
48     struct gfx_layer_params layer_param[DRM_HAL_GFX_MAX];
49 };
50 
51 static struct drm_hal_gfx_dev gfx_dev = {0};
52 
gfx_get_api(void)53 static hifb_drv_ops *gfx_get_api(void)
54 {
55     if (gfx_dev.params == NULL) {
56         return NULL;
57     }
58     return &(((struct hal_gfx_dev_params *)gfx_dev.params)->gfx_api);
59 }
60 
gfx_get_layer_param(enum drm_hal_gfx_layer layer)61 static struct gfx_layer_params *gfx_get_layer_param(enum drm_hal_gfx_layer layer)
62 {
63     int ret;
64 
65     if (layer >= DRM_HAL_GFX_MAX) {
66         return NULL;
67     }
68     /* has init */
69     if (gfx_dev.params != NULL) {
70         return &(((struct hal_gfx_dev_params *)gfx_dev.params)->layer_param[layer]);
71     }
72 
73     gfx_dev.params = kzalloc(sizeof(struct hal_gfx_dev_params), GFP_KERNEL);
74     if (gfx_dev.params == NULL) {
75         drm_hal_err("kzalloc err!\n");
76         return NULL;
77     }
78 
79     hifb_drv_get_ops(gfx_get_api());
80     /*
81      * can not init here, because hifb ko has inited
82      * gfx_api->hifb_drv_init()
83      */
84     ret = osal_spin_lock_init(&(gfx_dev.lock));
85     if (ret < 0) {
86         drm_hal_err("spinlock init failed!\n");
87         kfree(gfx_dev.params);
88         gfx_dev.params = NULL;
89         return NULL;
90     }
91 
92     return &(((struct hal_gfx_dev_params *)gfx_dev.params)->layer_param[layer]);
93 }
94 
gfx_layer_translate(enum drm_hal_gfx_layer layer)95 static int gfx_layer_translate(enum drm_hal_gfx_layer layer)
96 {
97     switch (layer) {
98         case DRM_HAL_GFX_G0:
99             return 0;
100         case DRM_HAL_GFX_G1:
101             return 1;
102         case DRM_HAL_GFX_G3:
103             return 2; /* 2:G3 */
104         default:
105             drm_hal_err("invalid layer id: %u\n", layer);
106             return -1;
107     }
108     return -1;
109 }
110 
drm_hal_gfx_deinit(void)111 static void drm_hal_gfx_deinit(void)
112 {
113     /*
114      * can not deinit here, because hifb ko has deinited
115      * gfx_api->hifb_drv_deinit()
116      */
117     if (gfx_dev.params != NULL) {
118         kfree(gfx_dev.params);
119         gfx_dev.params = NULL;
120     }
121     osal_spin_lock_destroy(&(gfx_dev.lock));
122     return;
123 }
124 
drm_hal_gfx_open(enum drm_hal_gfx_layer layer)125 static int drm_hal_gfx_open(enum drm_hal_gfx_layer layer)
126 {
127     unsigned long lock_flag;
128     struct gfx_layer_params *param = gfx_get_layer_param(layer);
129     int layer_id;
130     hal_gfx_check_ptr(param);
131 
132     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
133     if (param->open_cnt > 0) {
134         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
135         drm_hal_info("already opened, cnt=%d\n", param->open_cnt);
136         return 0;
137     }
138 
139     layer_id = gfx_layer_translate(layer);
140     if (layer_id == -1) {
141         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
142         return -1;
143     }
144 
145     param->layer_id = layer_id;
146     param->open_cnt++;
147     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
148     return 0;
149 }
150 
drm_hal_gfx_close(enum drm_hal_gfx_layer layer)151 static int drm_hal_gfx_close(enum drm_hal_gfx_layer layer)
152 {
153     unsigned long lock_flag;
154     struct gfx_layer_params *param = gfx_get_layer_param(layer);
155     hal_gfx_check_ptr(param);
156 
157     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
158     if (param->open_cnt <= 0) {
159         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
160         drm_hal_info("already closed, cnt=%d\n", param->open_cnt);
161         return 0;
162     }
163 
164     param->open_cnt--;
165     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
166     return 0;
167 }
168 
169 
gfx_callback(hi_u32 layer_id,hifb_main_intf_type type,void * para)170 static int gfx_callback(hi_u32 layer_id, hifb_main_intf_type type, void *para)
171 {
172     int ret = 0;
173     int i;
174     unsigned long lock_flag;
175     enum drm_hal_gfx_layer layer;
176     struct hal_gfx_dev_params *dev_param = (struct hal_gfx_dev_params *)gfx_dev.params;
177     hal_gfx_check_ptr(dev_param);
178 
179     switch (layer_id) {
180         case 0:
181             layer = DRM_HAL_GFX_G0;
182             break;
183         case 1:
184             layer = DRM_HAL_GFX_G1;
185             break;
186         case 2:
187             layer = DRM_HAL_GFX_G3;
188             break;
189         default:
190             return -1;
191     }
192     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
193     for (i = 0; i < DRM_HAL_GFX_MAX; i++) {
194         if ((dev_param->layer_param[i].layer_id == layer_id) &&
195             (dev_param->layer_param[i].open_cnt > 0) &&
196             (dev_param->layer_param[i].gfx_cb != NULL)) {
197             ret = dev_param->layer_param[i].gfx_cb(layer, DRM_HAL_GFX_CB_INTR_100, NULL);
198             break;
199         }
200     }
201 
202     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
203     return ret;
204 }
205 
drm_hal_gfx_enable(enum drm_hal_gfx_layer layer)206 static int drm_hal_gfx_enable(enum drm_hal_gfx_layer layer)
207 {
208     int ret;
209     unsigned long lock_flag;
210     struct gfx_layer_params *param = gfx_get_layer_param(layer);
211     hifb_drv_ops *gfx_api = gfx_get_api();
212     hal_gfx_check_ptr(param);
213     hal_gfx_check_ptr(gfx_api);
214 
215     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
216     if (param->open_cnt <= 0) {
217         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
218         drm_hal_err("layer not opened!\n");
219         return -1;
220     }
221 
222     /* this api should be called after vo enable, so we put it here */
223     ret = vou_graphics_init();
224     if (ret != 0) {
225         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
226         drm_hal_err("err, ret=%#x\n", ret);
227         return ret;
228     }
229 
230     ret = gfx_api->hifb_open_layer(param->layer_id);
231     if (ret != 0) {
232         drm_hal_err("err, ret=%#x, id=%u\n", ret, param->layer_id);
233         goto err_vou_gfx_deinit;
234     }
235 
236     ret = gfx_api->hifb_drv_layer_default_setting(param->layer_id);
237     if (ret != 0) {
238         drm_hal_err("err, ret=%#x, id=%u\n", ret, param->layer_id);
239         goto err_close_layer;
240     }
241 
242     hifb_main_reg_callback(param->layer_id, HIFB_INTTYPE_VO, gfx_callback);
243 
244     ret = gfx_api->hifb_drv_enable_layer(param->layer_id, HI_TRUE);
245     if (ret != 0) {
246         drm_hal_err("err, ret=%#x\n", ret);
247         goto err_unreg_callback;
248     }
249     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
250     return 0;
251 
252 err_unreg_callback:
253     hifb_main_reg_callback(param->layer_id, HIFB_INTTYPE_VO, HI_NULL);
254 err_close_layer:
255     (void)gfx_api->hifb_close_layer(param->layer_id);
256 err_vou_gfx_deinit:
257     (void)vou_graphics_deinit();
258     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
259     return ret;
260 }
261 
drm_hal_gfx_disable(enum drm_hal_gfx_layer layer)262 static int drm_hal_gfx_disable(enum drm_hal_gfx_layer layer)
263 {
264     int ret;
265     unsigned long lock_flag;
266     struct gfx_layer_params *param = gfx_get_layer_param(layer);
267     hifb_drv_ops *gfx_api = gfx_get_api();
268     hal_gfx_check_ptr(param);
269     hal_gfx_check_ptr(gfx_api);
270 
271     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
272     if (param->open_cnt <= 0) {
273         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
274         drm_hal_err("layer not opened!\n");
275         return -1;
276     }
277 
278     ret = gfx_api->hifb_drv_enable_layer(param->layer_id, HI_FALSE);
279     if (ret != 0) {
280         drm_hal_err("err, ret=%#x\n", ret);
281     }
282 
283     /* to be optimizing */
284     hifb_main_reg_callback(param->layer_id, HIFB_INTTYPE_VO, HI_NULL);
285 
286     ret = gfx_api->hifb_close_layer(param->layer_id);
287     if (ret != 0) {
288         drm_hal_err("err, ret=%#x\n", ret);
289     }
290 
291     ret = vou_graphics_deinit();
292     if (ret != 0) {
293         drm_hal_err("err, ret=%#x\n", ret);
294     }
295 
296     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
297     return ret;
298 }
299 
drm_hal_gfx_get_attr(enum drm_hal_gfx_layer layer,enum drm_hal_gfx_attr_type type,const void * param)300 static int drm_hal_gfx_get_attr(enum drm_hal_gfx_layer layer, enum drm_hal_gfx_attr_type type, const void *param)
301 {
302     (void)layer;
303     (void)type;
304     (void)param;
305     return 0;
306 }
307 
gfx_set_size(unsigned int id,struct drm_hal_rect * out_rect)308 static int gfx_set_size(unsigned int id, struct drm_hal_rect *out_rect)
309 {
310     HIFB_RECT in = {0};
311     HIFB_RECT out;
312     hifb_drv_ops *gfx_api = gfx_get_api();
313 
314     hal_gfx_check_ptr(gfx_api);
315 
316     out.x = out_rect->x;
317     out.y = out_rect->y;
318     out.w = out_rect->w;
319     out.h = out_rect->h;
320 
321     return gfx_api->hifb_drv_set_layer_rect(id, &in, &out);
322 }
323 
gfx_set_alpha(unsigned int id,unsigned int alpha)324 static int gfx_set_alpha(unsigned int id, unsigned int alpha)
325 {
326     HIFB_ALPHA_S hifb_alpha = {0};
327     hifb_drv_ops *gfx_api = gfx_get_api();
328 
329     hal_gfx_check_ptr(gfx_api);
330 
331     return gfx_api->hifb_drv_set_layer_alpha(id, hifb_alpha);
332 }
333 
gfx_set_zpos(unsigned int id,unsigned int zpos)334 static int gfx_set_zpos(unsigned int id, unsigned int zpos)
335 {
336     (void)id;
337     (void)zpos;
338     drm_hal_err("unsupported yet!\n");
339     return -1;
340 }
341 
gfx_set_format(unsigned int id,enum drm_hal_color_fmt fmt)342 static int gfx_set_format(unsigned int id, enum drm_hal_color_fmt fmt)
343 {
344     HIFB_COLOR_FMT_E hifb_fmt;
345     hifb_drv_ops *gfx_api = gfx_get_api();
346 
347     hal_gfx_check_ptr(gfx_api);
348     hal_gfx_check_ptr(gfx_api->hifb_drv_set_layer_data_fmt);
349 
350     switch (fmt) {
351         case DRM_HAL_FMT_ARGB8888:
352             hifb_fmt = DRM_HAL_FMT_ARGB8888;
353             break;
354         case DRM_HAL_FMT_ARGB1555:
355             hifb_fmt = DRM_HAL_FMT_ARGB1555;
356             break;
357         default:
358             hifb_fmt = DRM_HAL_FMT_ARGB8888;
359             break;
360     }
361 
362     return gfx_api->hifb_drv_set_layer_data_fmt(id, hifb_fmt);
363 }
364 
gfx_set_buffer(unsigned int id,unsigned long long addr)365 static int gfx_set_buffer(unsigned int id, unsigned long long addr)
366 {
367     hifb_drv_ops *gfx_api = gfx_get_api();
368 
369     hal_gfx_check_ptr(gfx_api);
370 
371     return gfx_api->hifb_drv_set_layer_addr(id, addr);
372 }
373 
gfx_set_stride(unsigned int id,unsigned int stride)374 static int gfx_set_stride(unsigned int id, unsigned int stride)
375 {
376     hifb_drv_ops *gfx_api = gfx_get_api();
377     hal_gfx_check_ptr(gfx_api);
378     return gfx_api->hifb_drv_set_layer_stride(id, stride);
379 }
380 
drm_hal_gfx_set_attr(enum drm_hal_gfx_layer layer,enum drm_hal_gfx_attr_type type,const void * param)381 static int drm_hal_gfx_set_attr(enum drm_hal_gfx_layer layer, enum drm_hal_gfx_attr_type type, const void *param)
382 {
383     int ret;
384     unsigned long lock_flag;
385     struct gfx_layer_params *layer_param = gfx_get_layer_param(layer);
386     hifb_drv_ops *gfx_api = gfx_get_api();
387 
388     hal_gfx_check_ptr(layer_param);
389     hal_gfx_check_ptr(gfx_api);
390 
391     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
392     if (layer_param->open_cnt <= 0) {
393         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
394         drm_hal_err("layer not opened!\n");
395         return -1;
396     }
397 
398     switch (type) {
399         case DRM_HAL_GFX_ATTR_SIZE:
400             ret = gfx_set_size(layer_param->layer_id, (struct drm_hal_rect *)param);
401             break;
402         case DRM_HAL_GFX_ATTR_ALPHA:
403             ret = gfx_set_alpha(layer_param->layer_id, *(unsigned int *)param);
404             break;
405         case DRM_HAL_GFX_ATTR_ZPOS:
406             ret = gfx_set_zpos(layer_param->layer_id, *(unsigned int *)param);
407             break;
408         case DRM_HAL_GFX_ATTR_FORMAT:
409             ret = gfx_set_format(layer_param->layer_id, *(enum drm_hal_color_fmt *)param);
410             break;
411         case DRM_HAL_GFX_ATTR_STRIDE:
412             ret = gfx_set_stride(layer_param->layer_id, *(unsigned int *)param);
413             break;
414         case DRM_HAL_GFX_ATTR_BUFFER:
415             ret = gfx_set_buffer(layer_param->layer_id, *(unsigned long long *)param);
416             break;
417         default:
418             drm_hal_err("attr type %d not support!\n", type);
419             ret = -1;
420     }
421 
422     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
423     return ret;
424 }
425 
drm_hal_gfx_register_cb(enum drm_hal_gfx_layer layer,enum drm_hal_gfx_cb_type type,drm_hal_gfx_cb cb)426 static int drm_hal_gfx_register_cb(enum drm_hal_gfx_layer layer, enum drm_hal_gfx_cb_type type, drm_hal_gfx_cb cb)
427 {
428     unsigned long lock_flag;
429     struct gfx_layer_params *param = gfx_get_layer_param(layer);
430     hifb_drv_ops *gfx_api = gfx_get_api();
431 
432     hal_gfx_check_ptr(param);
433     hal_gfx_check_ptr(gfx_api);
434 
435     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
436     if (param->open_cnt <= 0) {
437         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
438         drm_hal_err("layer not opened!\n");
439         return -1;
440     }
441 
442     param->gfx_cb = cb;
443     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
444     return 0;
445 }
446 
drm_hal_disp_unregister_cb(enum drm_hal_gfx_layer layer,enum drm_hal_gfx_cb_type type)447 static int drm_hal_disp_unregister_cb(enum drm_hal_gfx_layer layer, enum drm_hal_gfx_cb_type type)
448 {
449     unsigned long lock_flag;
450     struct gfx_layer_params *param = gfx_get_layer_param(layer);
451     hifb_drv_ops *gfx_api = gfx_get_api();
452 
453     hal_gfx_check_ptr(param);
454     hal_gfx_check_ptr(gfx_api);
455 
456     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
457     if (param->open_cnt <= 0) {
458         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
459         drm_hal_err("layer not opened!\n");
460         return -1;
461     }
462 
463     param->gfx_cb = NULL;
464     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
465     return 0;
466 }
467 
drm_hal_gfx_refresh(enum drm_hal_gfx_layer layer)468 static int drm_hal_gfx_refresh(enum drm_hal_gfx_layer layer)
469 {
470     int ret;
471     unsigned long lock_flag;
472     struct gfx_layer_params *param = gfx_get_layer_param(layer);
473     hifb_drv_ops *gfx_api = gfx_get_api();
474 
475     hal_gfx_check_ptr(param);
476     hal_gfx_check_ptr(gfx_api);
477 
478     osal_spin_lock_irqsave(&(gfx_dev.lock), &lock_flag);
479     if (param->open_cnt <= 0) {
480         osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
481         drm_hal_err("layer not opened!\n");
482         return -1;
483     }
484 
485     ret = gfx_api->hifb_drv_updata_layer_reg(param->layer_id);
486     if (ret != 0) {
487         drm_hal_err("err, ret=%#x\n", ret);
488     }
489     osal_spin_unlock_irqrestore(&(gfx_dev.lock), &lock_flag);
490     return 0;
491 }
492 
drm_hal_gfx_dev_register(hi_void)493 hi_void drm_hal_gfx_dev_register(hi_void)
494 {
495     hi_drm_export_func *drm_ext_func = HI_NULL;
496     drm_ext_func = drm_export_func_register();
497     if (drm_ext_func == HI_NULL) {
498         drm_hal_err("err:drm_ext_func is NULL!\n");
499         return;
500     }
501     drm_ext_func->gfx_func = &gfx_dev;
502     gfx_dev.deinit = drm_hal_gfx_deinit;
503     gfx_dev.open = drm_hal_gfx_open;
504     gfx_dev.close = drm_hal_gfx_close;
505     gfx_dev.enable = drm_hal_gfx_enable;
506     gfx_dev.disable = drm_hal_gfx_disable;
507     gfx_dev.get_attr = drm_hal_gfx_get_attr;
508     gfx_dev.set_attr = drm_hal_gfx_set_attr;
509     gfx_dev.register_cb = drm_hal_gfx_register_cb;
510     gfx_dev.unregister_cb = drm_hal_disp_unregister_cb;
511     gfx_dev.refresh = drm_hal_gfx_refresh;
512 
513     return;
514 }
515 
drm_hal_gfx_dev_unregister(hi_void)516 hi_void drm_hal_gfx_dev_unregister(hi_void)
517 {
518     hi_drm_export_func *drm_ext_func = HI_NULL;
519     drm_ext_func = drm_export_func_register();
520     if (drm_ext_func == HI_NULL) {
521         drm_hal_err("err:drm_ext_func is NULL!\n");
522         return;
523     }
524 
525     gfx_dev.deinit = NULL;
526     gfx_dev.open = NULL;
527     gfx_dev.close = NULL;
528     gfx_dev.enable = NULL;
529     gfx_dev.disable = NULL;
530     gfx_dev.get_attr = NULL;
531     gfx_dev.set_attr = NULL;
532     gfx_dev.register_cb = NULL;
533     gfx_dev.unregister_cb = NULL;
534     gfx_dev.refresh = NULL;
535     drm_ext_func->gfx_func = NULL;
536 
537     return;
538 }
539 
540