Home | History | Annotate | Download | only in libadf
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <dirent.h>
     18 #include <errno.h>
     19 #include <fcntl.h>
     20 #include <malloc.h>
     21 #include <stdint.h>
     22 #include <stdio.h>
     23 #include <string.h>
     24 #include <unistd.h>
     25 
     26 #include <linux/limits.h>
     27 
     28 #include <sys/ioctl.h>
     29 
     30 #include <adf/adf.h>
     31 
     32 #define ADF_BASE_PATH "/dev/"
     33 
     34 static ssize_t adf_find_nodes(const char *pattern, adf_id_t **ids)
     35 {
     36     DIR *dir;
     37     struct dirent *dirent;
     38     size_t n = 0;
     39     ssize_t ret;
     40     adf_id_t *ids_ret = NULL;
     41 
     42     dir = opendir(ADF_BASE_PATH);
     43     if (!dir)
     44         return -errno;
     45 
     46     errno = 0;
     47     while ((dirent = readdir(dir))) {
     48         adf_id_t id;
     49         int matched = sscanf(dirent->d_name, pattern, &id);
     50 
     51         if (matched < 0) {
     52             ret = -errno;
     53             goto done;
     54         } else if (matched != 1) {
     55             continue;
     56         }
     57 
     58         adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
     59         if (!new_ids) {
     60             ret = -ENOMEM;
     61             goto done;
     62         }
     63 
     64         ids_ret = new_ids;
     65         ids_ret[n] = id;
     66         n++;
     67     }
     68     if (errno)
     69         ret = -errno;
     70     else
     71         ret = n;
     72 
     73 done:
     74     closedir(dir);
     75     if (ret < 0)
     76         free(ids_ret);
     77     else
     78         *ids = ids_ret;
     79     return ret;
     80 }
     81 
     82 ssize_t adf_devices(adf_id_t **ids)
     83 {
     84     return adf_find_nodes("adf%u", ids);
     85 }
     86 
     87 int adf_device_open(adf_id_t id, int flags, struct adf_device *dev)
     88 {
     89     char filename[64];
     90     int err;
     91 
     92     dev->id = id;
     93 
     94     snprintf(filename, sizeof(filename), ADF_BASE_PATH "adf%u", id);
     95     dev->fd = open(filename, flags);
     96     if (dev->fd < 0)
     97         return -errno;
     98 
     99     return 0;
    100 }
    101 
    102 void adf_device_close(struct adf_device *dev)
    103 {
    104     if (dev->fd >= 0)
    105         close(dev->fd);
    106 }
    107 
    108 int adf_get_device_data(struct adf_device *dev, struct adf_device_data *data)
    109 {
    110     int err;
    111     int ret = 0;
    112 
    113     memset(data, 0, sizeof(*data));
    114 
    115     err = ioctl(dev->fd, ADF_GET_DEVICE_DATA, data);
    116     if (err < 0)
    117         return -ENOMEM;
    118 
    119     if (data->n_attachments) {
    120         data->attachments = malloc(sizeof(data->attachments[0]) *
    121                 data->n_attachments);
    122         if (!data->attachments)
    123             return -ENOMEM;
    124     }
    125 
    126     if (data->n_allowed_attachments) {
    127         data->allowed_attachments =
    128                 malloc(sizeof(data->allowed_attachments[0]) *
    129                         data->n_allowed_attachments);
    130         if (!data->allowed_attachments) {
    131             ret = -ENOMEM;
    132             goto done;
    133         }
    134     }
    135 
    136     if (data->custom_data_size) {
    137         data->custom_data = malloc(data->custom_data_size);
    138         if (!data->custom_data) {
    139             ret = -ENOMEM;
    140             goto done;
    141         }
    142     }
    143 
    144     err = ioctl(dev->fd, ADF_GET_DEVICE_DATA, data);
    145     if (err < 0)
    146         ret = -errno;
    147 
    148 done:
    149     if (ret < 0)
    150         adf_free_device_data(data);
    151     return ret;
    152 }
    153 
    154 void adf_free_device_data(struct adf_device_data *data)
    155 {
    156     free(data->attachments);
    157     free(data->allowed_attachments);
    158     free(data->custom_data);
    159 }
    160 
    161 int adf_device_post(struct adf_device *dev,
    162         adf_id_t *interfaces, size_t n_interfaces,
    163         struct adf_buffer_config *bufs, size_t n_bufs,
    164         void *custom_data, size_t custom_data_size)
    165 {
    166     int err;
    167     struct adf_post_config data;
    168 
    169     memset(&data, 0, sizeof(data));
    170     data.interfaces = interfaces;
    171     data.n_interfaces = n_interfaces;
    172     data.bufs = bufs;
    173     data.n_bufs = n_bufs;
    174     data.custom_data = custom_data;
    175     data.custom_data_size = custom_data_size;
    176 
    177     err = ioctl(dev->fd, ADF_POST_CONFIG, &data);
    178     if (err < 0)
    179         return -errno;
    180 
    181     return (int)data.complete_fence;
    182 }
    183 
    184 static int adf_device_attachment(struct adf_device *dev,
    185         adf_id_t overlay_engine, adf_id_t interface, bool attach)
    186 {
    187     int err;
    188     struct adf_attachment_config data;
    189 
    190     memset(&data, 0, sizeof(data));
    191     data.overlay_engine = overlay_engine;
    192     data.interface = interface;
    193 
    194     err = ioctl(dev->fd, attach ? ADF_ATTACH : ADF_DETACH, &data);
    195     if (err < 0)
    196         return -errno;
    197 
    198     return 0;
    199 }
    200 
    201 int adf_device_attach(struct adf_device *dev, adf_id_t overlay_engine,
    202                       adf_id_t interface)
    203 {
    204    return adf_device_attachment(dev, overlay_engine, interface, true);
    205 }
    206 
    207 int adf_device_detach(struct adf_device *dev, adf_id_t overlay_engine,
    208                       adf_id_t interface)
    209 {
    210    return adf_device_attachment(dev, overlay_engine, interface, false);
    211 }
    212 
    213 ssize_t adf_interfaces(struct adf_device *dev, adf_id_t **interfaces)
    214 {
    215     char pattern[64];
    216 
    217     snprintf(pattern, sizeof(pattern), "adf-interface%u.%%u", dev->id);
    218     return adf_find_nodes(pattern, interfaces);
    219 }
    220 
    221 ssize_t adf_interfaces_for_overlay_engine(struct adf_device *dev,
    222         adf_id_t overlay_engine, adf_id_t **interfaces)
    223 {
    224     struct adf_device_data data;
    225     ssize_t n = 0;
    226     ssize_t ret;
    227     adf_id_t *ids_ret = NULL;
    228 
    229     ret = adf_get_device_data(dev, &data);
    230     if (ret < 0)
    231         return ret;
    232 
    233     size_t i;
    234     for (i = 0; i < data.n_allowed_attachments; i++) {
    235         if (data.allowed_attachments[i].overlay_engine != overlay_engine)
    236             continue;
    237 
    238         adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
    239         if (!new_ids) {
    240             ret = -ENOMEM;
    241             goto done;
    242         }
    243 
    244         ids_ret = new_ids;
    245         ids_ret[n] = data.allowed_attachments[i].interface;
    246         n++;
    247     }
    248 
    249     ret = n;
    250 
    251 done:
    252     adf_free_device_data(&data);
    253     if (ret < 0)
    254         free(ids_ret);
    255     else
    256         *interfaces = ids_ret;
    257     return ret;
    258 }
    259 
    260 static ssize_t adf_interfaces_filter(struct adf_device *dev,
    261         adf_id_t *in, size_t n_in, adf_id_t **out,
    262         bool (*filter)(struct adf_interface_data *data, __u32 match),
    263         __u32 match)
    264 {
    265     size_t n = 0;
    266     ssize_t ret;
    267     adf_id_t *ids_ret = NULL;
    268 
    269     size_t i;
    270     for (i = 0; i < n_in; i++) {
    271         int fd = adf_interface_open(dev, in[i], O_RDONLY);
    272         if (fd < 0) {
    273             ret = fd;
    274             goto done;
    275         }
    276 
    277         struct adf_interface_data data;
    278         ret = adf_get_interface_data(fd, &data);
    279         close(fd);
    280         if (ret < 0)
    281             goto done;
    282 
    283         if (!filter(&data, match))
    284             continue;
    285 
    286         adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
    287         if (!new_ids) {
    288             ret = -ENOMEM;
    289             goto done;
    290         }
    291 
    292         ids_ret = new_ids;
    293         ids_ret[n] = in[i];
    294         n++;
    295     }
    296 
    297     ret = n;
    298 
    299 done:
    300     if (ret < 0)
    301         free(ids_ret);
    302     else
    303         *out = ids_ret;
    304     return ret;
    305 }
    306 
    307 static bool adf_interface_type_filter(struct adf_interface_data *data,
    308         __u32 type)
    309 {
    310     return data->type == (enum adf_interface_type)type;
    311 }
    312 
    313 ssize_t adf_interfaces_filter_by_type(struct adf_device *dev,
    314         enum adf_interface_type type,
    315         adf_id_t *in, size_t n_in, adf_id_t **out)
    316 {
    317     return adf_interfaces_filter(dev, in, n_in, out, adf_interface_type_filter,
    318             type);
    319 }
    320 
    321 static bool adf_interface_flags_filter(struct adf_interface_data *data,
    322         __u32 flag)
    323 {
    324     return !!(data->flags & flag);
    325 }
    326 
    327 ssize_t adf_interfaces_filter_by_flag(struct adf_device *dev, __u32 flag,
    328         adf_id_t *in, size_t n_in, adf_id_t **out)
    329 {
    330     return adf_interfaces_filter(dev, in, n_in, out, adf_interface_flags_filter,
    331             flag);
    332 }
    333 
    334 int adf_interface_open(struct adf_device *dev, adf_id_t id, int flags)
    335 {
    336     char filename[64];
    337 
    338     snprintf(filename, sizeof(filename), ADF_BASE_PATH "adf-interface%u.%u",
    339             dev->id, id);
    340 
    341     int fd = open(filename, flags);
    342     if (fd < 0)
    343         return -errno;
    344     return fd;
    345 }
    346 
    347 int adf_get_interface_data(int fd, struct adf_interface_data *data)
    348 {
    349     int err;
    350     int ret = 0;
    351 
    352     memset(data, 0, sizeof(*data));
    353 
    354     err = ioctl(fd, ADF_GET_INTERFACE_DATA, data);
    355     if (err < 0)
    356         return -errno;
    357 
    358     if (data->n_available_modes) {
    359         data->available_modes = malloc(sizeof(data->available_modes[0]) *
    360                 data->n_available_modes);
    361         if (!data->available_modes)
    362             return -ENOMEM;
    363     }
    364 
    365     if (data->custom_data_size) {
    366         data->custom_data = malloc(data->custom_data_size);
    367         if (!data->custom_data) {
    368             ret = -ENOMEM;
    369             goto done;
    370         }
    371     }
    372 
    373     err = ioctl(fd, ADF_GET_INTERFACE_DATA, data);
    374     if (err < 0)
    375         ret = -errno;
    376 
    377 done:
    378     if (ret < 0)
    379         adf_free_interface_data(data);
    380     return ret;
    381 }
    382 
    383 void adf_free_interface_data(struct adf_interface_data *data)
    384 {
    385     free(data->available_modes);
    386     free(data->custom_data);
    387 }
    388 
    389 int adf_interface_blank(int fd, __u8 mode)
    390 {
    391     int err = ioctl(fd, ADF_BLANK, mode);
    392     if (err < 0)
    393         return -errno;
    394     return 0;
    395 }
    396 
    397 int adf_interface_set_mode(int fd, struct drm_mode_modeinfo *mode)
    398 {
    399     int err = ioctl(fd, ADF_SET_MODE, mode);
    400     if (err < 0)
    401         return -errno;
    402     return 0;
    403 }
    404 
    405 int adf_interface_simple_buffer_alloc(int fd, __u32 w, __u32 h,
    406         __u32 format, __u32 *offset, __u32 *pitch)
    407 {
    408     int err;
    409     struct adf_simple_buffer_alloc data;
    410 
    411     memset(&data, 0, sizeof(data));
    412     data.w = w;
    413     data.h = h;
    414     data.format = format;
    415 
    416     err = ioctl(fd, ADF_SIMPLE_BUFFER_ALLOC, &data);
    417     if (err < 0)
    418         return -errno;
    419 
    420     *offset = data.offset;
    421     *pitch = data.pitch;
    422     return (int)data.fd;
    423 }
    424 
    425 int adf_interface_simple_post(int fd, __u32 overlay_engine,
    426         __u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
    427         __u32 pitch, int acquire_fence)
    428 {
    429     int ret;
    430     struct adf_simple_post_config data;
    431 
    432     memset(&data, 0, sizeof(data));
    433     data.buf.overlay_engine = overlay_engine;
    434     data.buf.w = w;
    435     data.buf.h = h;
    436     data.buf.format = format;
    437     data.buf.fd[0] = buf_fd;
    438     data.buf.offset[0] = offset;
    439     data.buf.pitch[0] = pitch;
    440     data.buf.n_planes = 1;
    441     data.buf.acquire_fence = acquire_fence;
    442 
    443     ret = ioctl(fd, ADF_SIMPLE_POST_CONFIG, &data);
    444     if (ret < 0)
    445         return -errno;
    446 
    447     return (int)data.complete_fence;
    448 }
    449 
    450 ssize_t adf_overlay_engines(struct adf_device *dev, adf_id_t **overlay_engines)
    451 {
    452     char pattern[64];
    453 
    454     snprintf(pattern, sizeof(pattern), "adf-overlay-engine%u.%%u", dev->id);
    455     return adf_find_nodes(pattern, overlay_engines);
    456 }
    457 
    458 ssize_t adf_overlay_engines_for_interface(struct adf_device *dev,
    459         adf_id_t interface, adf_id_t **overlay_engines)
    460 {
    461     struct adf_device_data data;
    462     ssize_t n = 0;
    463     ssize_t ret;
    464     adf_id_t *ids_ret = NULL;
    465 
    466     ret = adf_get_device_data(dev, &data);
    467     if (ret < 0)
    468         return ret;
    469 
    470     size_t i;
    471     for (i = 0; i < data.n_allowed_attachments; i++) {
    472         if (data.allowed_attachments[i].interface != interface)
    473             continue;
    474 
    475         adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
    476         if (!new_ids) {
    477             ret = -ENOMEM;
    478             goto done;
    479         }
    480 
    481         ids_ret = new_ids;
    482         ids_ret[n] = data.allowed_attachments[i].overlay_engine;
    483         n++;
    484     }
    485 
    486     ret = n;
    487 
    488 done:
    489     adf_free_device_data(&data);
    490     if (ret < 0)
    491         free(ids_ret);
    492     else
    493         *overlay_engines = ids_ret;
    494     return ret;
    495 }
    496 
    497 static ssize_t adf_overlay_engines_filter(struct adf_device *dev,
    498         adf_id_t *in, size_t n_in, adf_id_t **out,
    499         bool (*filter)(struct adf_overlay_engine_data *data, void *cookie),
    500         void *cookie)
    501 {
    502     size_t n = 0;
    503     ssize_t ret;
    504     adf_id_t *ids_ret = NULL;
    505 
    506     size_t i;
    507     for (i = 0; i < n_in; i++) {
    508         int fd = adf_overlay_engine_open(dev, in[i], O_RDONLY);
    509         if (fd < 0) {
    510             ret = fd;
    511             goto done;
    512         }
    513 
    514         struct adf_overlay_engine_data data;
    515         ret = adf_get_overlay_engine_data(fd, &data);
    516         close(fd);
    517         if (ret < 0)
    518             goto done;
    519 
    520         if (!filter(&data, cookie))
    521             continue;
    522 
    523         adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
    524         if (!new_ids) {
    525             ret = -ENOMEM;
    526             goto done;
    527         }
    528 
    529         ids_ret = new_ids;
    530         ids_ret[n] = in[i];
    531         n++;
    532     }
    533 
    534     ret = n;
    535 
    536 done:
    537     if (ret < 0)
    538         free(ids_ret);
    539     else
    540         *out = ids_ret;
    541     return ret;
    542 }
    543 
    544 struct format_filter_cookie {
    545     const __u32 *formats;
    546     size_t n_formats;
    547 };
    548 
    549 static bool adf_overlay_engine_format_filter(
    550         struct adf_overlay_engine_data *data, void *cookie)
    551 {
    552     struct format_filter_cookie *c = cookie;
    553     size_t i;
    554     for (i = 0; i < data->n_supported_formats; i++) {
    555         size_t j;
    556         for (j = 0; j < c->n_formats; j++)
    557             if (data->supported_formats[i] == c->formats[j])
    558                 return true;
    559     }
    560     return false;
    561 }
    562 
    563 ssize_t adf_overlay_engines_filter_by_format(struct adf_device *dev,
    564         const __u32 *formats, size_t n_formats, adf_id_t *in, size_t n_in,
    565         adf_id_t **out)
    566 {
    567     struct format_filter_cookie cookie = { formats, n_formats };
    568     return adf_overlay_engines_filter(dev, in, n_in, out,
    569             adf_overlay_engine_format_filter, &cookie);
    570 }
    571 
    572 int adf_overlay_engine_open(struct adf_device *dev, adf_id_t id, int flags)
    573 {
    574     char filename[64];
    575 
    576     snprintf(filename, sizeof(filename),
    577             ADF_BASE_PATH "adf-overlay-engine%u.%u", dev->id, id);
    578 
    579     int fd = open(filename, flags);
    580     if (fd < 0)
    581         return -errno;
    582     return fd;
    583 }
    584 
    585 int adf_get_overlay_engine_data(int fd, struct adf_overlay_engine_data *data)
    586 {
    587     int err;
    588     int ret = 0;
    589 
    590     memset(data, 0, sizeof(*data));
    591 
    592     err = ioctl(fd, ADF_GET_OVERLAY_ENGINE_DATA, data);
    593     if (err < 0)
    594         return -errno;
    595 
    596     if (data->n_supported_formats) {
    597         data->supported_formats = malloc(sizeof(data->supported_formats[0]) *
    598               data->n_supported_formats);
    599         if (!data->supported_formats)
    600             return -ENOMEM;
    601     }
    602 
    603     if (data->custom_data_size) {
    604       data->custom_data = malloc(data->custom_data_size);
    605       if (!data->custom_data) {
    606           ret = -ENOMEM;
    607           goto done;
    608       }
    609     }
    610 
    611     err = ioctl(fd, ADF_GET_OVERLAY_ENGINE_DATA, data);
    612     if (err < 0)
    613         ret = -errno;
    614 
    615 done:
    616     if (ret < 0)
    617         adf_free_overlay_engine_data(data);
    618     return ret;
    619 }
    620 
    621 void adf_free_overlay_engine_data(struct adf_overlay_engine_data *data)
    622 {
    623     free(data->supported_formats);
    624     free(data->custom_data);
    625 }
    626 
    627 bool adf_overlay_engine_supports_format(int fd, __u32 format)
    628 {
    629     struct adf_overlay_engine_data data;
    630     bool ret = false;
    631     size_t i;
    632 
    633     int err = adf_get_overlay_engine_data(fd, &data);
    634     if (err < 0)
    635         return false;
    636 
    637     for (i = 0; i < data.n_supported_formats; i++) {
    638         if (data.supported_formats[i] == format) {
    639             ret = true;
    640             break;
    641         }
    642     }
    643 
    644     adf_free_overlay_engine_data(&data);
    645     return ret;
    646 }
    647 
    648 int adf_set_event(int fd, enum adf_event_type type, bool enabled)
    649 {
    650     struct adf_set_event data;
    651 
    652     data.type = type;
    653     data.enabled = enabled;
    654 
    655     int err = ioctl(fd, ADF_SET_EVENT, &data);
    656     if (err < 0)
    657         return -errno;
    658     return 0;
    659 }
    660 
    661 int adf_read_event(int fd, struct adf_event **event)
    662 {
    663     struct adf_event header;
    664     struct {
    665         struct adf_event base;
    666         uint8_t data[0];
    667     } *event_ret;
    668     size_t data_size;
    669     int ret = 0;
    670 
    671     int err = read(fd, &header, sizeof(header));
    672     if (err < 0)
    673         return -errno;
    674     if ((size_t)err < sizeof(header))
    675         return -EIO;
    676     if (header.length < sizeof(header))
    677         return -EIO;
    678 
    679     event_ret = malloc(header.length);
    680     if (!event_ret)
    681         return -ENOMEM;
    682     data_size = header.length - sizeof(header);
    683 
    684     memcpy(event_ret, &header, sizeof(header));
    685     ssize_t read_size = read(fd, &event_ret->data, data_size);
    686     if (read_size < 0) {
    687         ret = -errno;
    688         goto done;
    689     }
    690     if ((size_t)read_size < data_size) {
    691         ret = -EIO;
    692         goto done;
    693     }
    694 
    695     *event = &event_ret->base;
    696 
    697 done:
    698     if (ret < 0)
    699         free(event_ret);
    700     return ret;
    701 }
    702 
    703 void adf_format_str(__u32 format, char buf[ADF_FORMAT_STR_SIZE])
    704 {
    705     buf[0] = format & 0xFF;
    706     buf[1] = (format >> 8) & 0xFF;
    707     buf[2] = (format >> 16) & 0xFF;
    708     buf[3] = (format >> 24) & 0xFF;
    709     buf[4] = '\0';
    710 }
    711 
    712 static bool adf_find_simple_post_overlay_engine(struct adf_device *dev,
    713         const __u32 *formats, size_t n_formats,
    714         adf_id_t interface, adf_id_t *overlay_engine)
    715 {
    716     adf_id_t *engs;
    717     ssize_t n_engs = adf_overlay_engines_for_interface(dev, interface, &engs);
    718 
    719     if (n_engs <= 0)
    720         return false;
    721 
    722     adf_id_t *filtered_engs;
    723     ssize_t n_filtered_engs = adf_overlay_engines_filter_by_format(dev,
    724             formats, n_formats, engs, n_engs, &filtered_engs);
    725     free(engs);
    726 
    727     if (n_filtered_engs <= 0)
    728         return false;
    729 
    730     *overlay_engine = filtered_engs[0];
    731     free(filtered_engs);
    732     return true;
    733 }
    734 
    735 static const __u32 any_rgb_format[] = {
    736     DRM_FORMAT_C8,
    737     DRM_FORMAT_RGB332,
    738     DRM_FORMAT_BGR233,
    739     DRM_FORMAT_XRGB1555,
    740     DRM_FORMAT_XBGR1555,
    741     DRM_FORMAT_RGBX5551,
    742     DRM_FORMAT_BGRX5551,
    743     DRM_FORMAT_ARGB1555,
    744     DRM_FORMAT_ABGR1555,
    745     DRM_FORMAT_RGBA5551,
    746     DRM_FORMAT_BGRA5551,
    747     DRM_FORMAT_RGB565,
    748     DRM_FORMAT_BGR565,
    749     DRM_FORMAT_RGB888,
    750     DRM_FORMAT_BGR888,
    751     DRM_FORMAT_XRGB8888,
    752     DRM_FORMAT_XBGR8888,
    753     DRM_FORMAT_RGBX8888,
    754     DRM_FORMAT_BGRX8888,
    755     DRM_FORMAT_XRGB2101010,
    756     DRM_FORMAT_XBGR2101010,
    757     DRM_FORMAT_RGBX1010102,
    758     DRM_FORMAT_BGRX1010102,
    759     DRM_FORMAT_ARGB2101010,
    760     DRM_FORMAT_ABGR2101010,
    761     DRM_FORMAT_RGBA1010102,
    762     DRM_FORMAT_BGRA1010102,
    763     DRM_FORMAT_ARGB8888,
    764     DRM_FORMAT_ABGR8888,
    765     DRM_FORMAT_RGBA8888,
    766     DRM_FORMAT_BGRA8888,
    767 };
    768 
    769 int adf_find_simple_post_configuration(struct adf_device *dev,
    770         const __u32 *formats, size_t n_formats,
    771         adf_id_t *interface, adf_id_t *overlay_engine)
    772 {
    773     adf_id_t *intfs = NULL;
    774     ssize_t n_intfs = adf_interfaces(dev, &intfs);
    775 
    776     if (n_intfs < 0)
    777         return n_intfs;
    778     else if (!n_intfs)
    779         return -ENODEV;
    780 
    781     adf_id_t *primary_intfs;
    782     ssize_t n_primary_intfs = adf_interfaces_filter_by_flag(dev,
    783             ADF_INTF_FLAG_PRIMARY, intfs, n_intfs, &primary_intfs);
    784     free(intfs);
    785 
    786     if (n_primary_intfs < 0)
    787         return n_primary_intfs;
    788     else if (!n_primary_intfs)
    789         return -ENODEV;
    790 
    791     if (!formats) {
    792         formats = any_rgb_format;
    793         n_formats = sizeof(any_rgb_format) / sizeof(any_rgb_format[0]);
    794     }
    795 
    796     bool found = false;
    797     ssize_t i = 0;
    798     for (i = 0; i < n_primary_intfs; i++) {
    799         found = adf_find_simple_post_overlay_engine(dev, formats, n_formats,
    800                 primary_intfs[i], overlay_engine);
    801         if (found) {
    802             *interface = primary_intfs[i];
    803             break;
    804         }
    805     }
    806     free(primary_intfs);
    807 
    808     if (!found)
    809         return -ENODEV;
    810 
    811     return 0;
    812 }
    813