Ignore:
Timestamp:
2020-02-25T10:47:32Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e6e77f
Parents:
265989d
git-author:
Jiri Svoboda <jiri@…> (2020-02-24 20:47:13)
git-committer:
Jiri Svoboda <jiri@…> (2020-02-25 10:47:32)
Message:

Best effort to port amdm37x display driver to libdisplay/libgfx

I couldn't test this. According to JanV this driver only works in
Linaro Qemu, but that is unmaintained and latest revision from git
crashed on me when I ran qemu-system-arm -machine beaglexm.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c

    r265989d r2a515dcd  
    11/*
     2 * Copyright (c) 2020 Jiri Svoboda
    23 * Copyright (c) 2013 Jan Vesely
    34 * All rights reserved.
     
    3536
    3637#include <align.h>
     38#include <as.h>
    3739#include <assert.h>
    3840#include <errno.h>
     41#include <ddev_srv.h>
     42#include <ddev/info.h>
     43#include <ddf/driver.h>
    3944#include <ddf/log.h>
    4045#include <ddi.h>
    41 #include <as.h>
     46#include <gfx/color.h>
     47#include <io/pixelmap.h>
    4248
    4349#include "amdm37x_dispc.h"
     
    5561#endif
    5662
    57 static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
    58 static errno_t handle_damage(visualizer_t *vs,
    59     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    60     sysarg_t x_offset, sysarg_t y_offset);
    61 static errno_t dummy(visualizer_t *vs)
    62 {
    63         return EOK;
    64 }
    65 
    66 static const visualizer_ops_t amdm37x_dispc_vis_ops = {
    67         .change_mode = change_mode,
    68         .handle_damage = handle_damage,
    69         .claim = dummy,
    70         .yield = dummy,
    71         .suspend = dummy,
    72         .wakeup = dummy,
     63static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned,
     64    visual_t);
     65
     66static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     67static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *);
     68
     69static errno_t amdm37x_gc_set_color(void *, gfx_color_t *);
     70static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *);
     71static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     72    gfx_bitmap_alloc_t *, void **);
     73static errno_t amdm37x_gc_bitmap_destroy(void *);
     74static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     75static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     76
     77ddev_ops_t amdm37x_ddev_ops = {
     78        .get_gc = amdm37x_ddev_get_gc,
     79        .get_info = amdm37x_ddev_get_info
     80};
     81
     82gfx_context_ops_t amdm37x_gc_ops = {
     83        .set_color = amdm37x_gc_set_color,
     84        .fill_rect = amdm37x_gc_fill_rect,
     85        .bitmap_create = amdm37x_gc_bitmap_create,
     86        .bitmap_destroy = amdm37x_gc_bitmap_destroy,
     87        .bitmap_render = amdm37x_gc_bitmap_render,
     88        .bitmap_get_alloc = amdm37x_gc_bitmap_get_alloc
    7389};
    7490
     
    94110};
    95111
    96 static void mode_init(vslmode_list_element_t *mode,
    97     unsigned width, unsigned height, visual_t visual)
    98 {
    99         mode->mode.index = 0;
    100         mode->mode.version = 0;
    101         mode->mode.refresh_rate = 0;
    102         mode->mode.screen_aspect.width = width;
    103         mode->mode.screen_aspect.height = height;
    104         mode->mode.screen_width = width;
    105         mode->mode.screen_height = height;
    106         mode->mode.cell_aspect.width = 1;
    107         mode->mode.cell_aspect.height = 1;
    108         mode->mode.cell_visual.pixel_visual = visual;
    109 
    110         link_initialize(&mode->link);
    111 
    112 }
    113 
    114 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
    115 {
    116         assert(instance);
    117         assert(vis);
    118 
     112errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun)
     113{
     114        instance->fun = fun;
    119115        instance->fb_data = NULL;
    120116        instance->size = 0;
     
    145141        }
    146142
    147         mode_init(&instance->modes[0],
    148             CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, visual);
    149 
    150         /* Handle vis stuff */
    151         vis->dev_ctx = instance;
    152         vis->def_mode_idx = 0;
    153         vis->ops = amdm37x_dispc_vis_ops;
    154         list_append(&instance->modes[0].link, &vis->modes);
     143        ret = amdm37x_change_mode(instance, CONFIG_BFB_WIDTH,
     144            CONFIG_BFB_HEIGHT, visual);
     145        if (ret != EOK)
     146                return EIO;
    155147
    156148        return EOK;
     
    269261}
    270262
    271 static errno_t change_mode(visualizer_t *vis, vslmode_t mode)
    272 {
    273         assert(vis);
    274         assert(vis->dev_ctx);
    275 
    276         amdm37x_dispc_t *dispc = vis->dev_ctx;
    277         const visual_t visual = mode.cell_visual.pixel_visual;
     263static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x,
     264    unsigned y, visual_t visual)
     265{
    278266        assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
    279267        const unsigned bpp = pixel2visual_table[visual].bpp;
    280268        pixel2visual_t p2v = pixel2visual_table[visual].func;
    281         const unsigned x = mode.screen_width;
    282         const unsigned y = mode.screen_height;
    283269        ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8);
    284270        const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
     
    296282        dispc->fb_data = buffer;
    297283        amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa);
    298         dispc->active_fb.idx = mode.index;
    299284        dispc->active_fb.width = x;
    300285        dispc->active_fb.height = y;
     
    302287        dispc->active_fb.bpp = bpp;
    303288        dispc->active_fb.pixel2visual = p2v;
     289        dispc->rect.p0.x = 0;
     290        dispc->rect.p0.y = 0;
     291        dispc->rect.p1.x = x;
     292        dispc->rect.p1.y = y;
    304293        dispc->size = size;
    305         assert(mode.index < 1);
    306 
    307         return EOK;
    308 }
    309 
    310 static errno_t handle_damage(visualizer_t *vs,
    311     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    312     sysarg_t x_offset, sysarg_t y_offset)
    313 {
    314         assert(vs);
    315         assert(vs->dev_ctx);
    316         amdm37x_dispc_t *dispc = vs->dev_ctx;
    317         pixelmap_t *map = &vs->cells;
    318 
    319 #define FB_POS(x, y) \
    320         (((y) * (dispc->active_fb.width + dispc->active_fb.pitch) + (x)) \
    321             * dispc->active_fb.bpp)
    322         if (x_offset == 0 && y_offset == 0) {
    323                 /* Faster damage routine ignoring offsets. */
    324                 for (sysarg_t y = y0; y < height + y0; ++y) {
    325                         pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
    326                         for (sysarg_t x = x0; x < width + x0; ++x) {
    327                                 dispc->active_fb.pixel2visual(
    328                                     dispc->fb_data + FB_POS(x, y), *pixel++);
    329                         }
     294
     295        return EOK;
     296}
     297
     298#define FB_POS(d, x, y) \
     299    (((y) * ((d)->active_fb.width + (d)->active_fb.pitch) + (x)) \
     300    * (d)->active_fb.bpp)
     301
     302static errno_t amdm37x_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
     303{
     304        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     305
     306        *arg2 = ddf_fun_get_handle(dispc->fun);
     307        *arg3 = 42;
     308        return EOK;
     309}
     310
     311static errno_t amdm37x_ddev_get_info(void *arg, ddev_info_t *info)
     312{
     313        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     314
     315        ddev_info_init(info);
     316        info->rect.p0.x = 0;
     317        info->rect.p0.y = 0;
     318        info->rect.p1.x = dispc->active_fb.width;
     319        info->rect.p1.y = dispc->active_fb.height;
     320        return EOK;
     321}
     322
     323/** Set color on AMDM37x display controller.
     324 *
     325 * Set drawing color on AMDM37x GC.
     326 *
     327 * @param arg AMDM37x display controller
     328 * @param color Color
     329 *
     330 * @return EOK on success or an error code
     331 */
     332static errno_t amdm37x_gc_set_color(void *arg, gfx_color_t *color)
     333{
     334        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     335        uint16_t r, g, b;
     336
     337        gfx_color_get_rgb_i16(color, &r, &g, &b);
     338        dispc->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     339        return EOK;
     340}
     341
     342/** Fill rectangle on AMDM37x display controller.
     343 *
     344 * @param arg AMDM37x display controller
     345 * @param rect Rectangle
     346 *
     347 * @return EOK on success or an error code
     348 */
     349static errno_t amdm37x_gc_fill_rect(void *arg, gfx_rect_t *rect)
     350{
     351        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     352        gfx_rect_t crect;
     353        gfx_coord_t x, y;
     354
     355        /* Make sure we have a sorted, clipped rectangle */
     356        gfx_rect_clip(rect, &dispc->rect, &crect);
     357
     358        for (y = crect.p0.y; y < crect.p1.y; y++) {
     359                for (x = crect.p0.x; x < crect.p1.x; x++) {
     360                        dispc->active_fb.pixel2visual(dispc->fb_data +
     361                            FB_POS(dispc, x, y), dispc->color);
     362                }
     363        }
     364
     365        return EOK;
     366}
     367
     368/** Create bitmap in AMDM37x GC.
     369 *
     370 * @param arg AMDM37x display controller
     371 * @param params Bitmap params
     372 * @param alloc Bitmap allocation info or @c NULL
     373 * @param rbm Place to store pointer to new bitmap
     374 * @return EOK on success or an error code
     375 */
     376errno_t amdm37x_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     377    gfx_bitmap_alloc_t *alloc, void **rbm)
     378{
     379        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     380        amdm37x_bitmap_t *dcbm = NULL;
     381        gfx_coord2_t dim;
     382        errno_t rc;
     383
     384        dcbm = calloc(1, sizeof(amdm37x_bitmap_t));
     385        if (dcbm == NULL)
     386                return ENOMEM;
     387
     388        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     389        dcbm->rect = params->rect;
     390
     391        if (alloc == NULL) {
     392                dcbm->alloc.pitch = dim.x * sizeof(uint32_t);
     393                dcbm->alloc.off0 = 0;
     394                dcbm->alloc.pixels = malloc(dcbm->alloc.pitch * dim.y);
     395                dcbm->myalloc = true;
     396
     397                if (dcbm->alloc.pixels == NULL) {
     398                        rc = ENOMEM;
     399                        goto error;
    330400                }
    331401        } else {
    332                 for (sysarg_t y = y0; y < height + y0; ++y) {
    333                         for (sysarg_t x = x0; x < width + x0; ++x) {
    334                                 dispc->active_fb.pixel2visual(
    335                                     dispc->fb_data + FB_POS(x, y),
    336                                     *pixelmap_pixel_at(map,
    337                                     (x + x_offset) % map->width,
    338                                     (y + y_offset) % map->height));
    339                         }
     402                dcbm->alloc = *alloc;
     403        }
     404
     405        dcbm->dispc = dispc;
     406        *rbm = (void *)dcbm;
     407        return EOK;
     408error:
     409        if (rbm != NULL)
     410                free(dcbm);
     411        return rc;
     412}
     413
     414/** Destroy bitmap in AMDM37x GC.
     415 *
     416 * @param bm Bitmap
     417 * @return EOK on success or an error code
     418 */
     419static errno_t amdm37x_gc_bitmap_destroy(void *bm)
     420{
     421        amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
     422        if (dcbm->myalloc)
     423                free(dcbm->alloc.pixels);
     424        free(dcbm);
     425        return EOK;
     426}
     427
     428/** Render bitmap in AMDM37x GC.
     429 *
     430 * @param bm Bitmap
     431 * @param srect0 Source rectangle or @c NULL
     432 * @param offs0 Offset or @c NULL
     433 * @return EOK on success or an error code
     434 */
     435static errno_t amdm37x_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     436    gfx_coord2_t *offs0)
     437{
     438        amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
     439        amdm37x_dispc_t *dispc = dcbm->dispc;
     440        gfx_rect_t srect;
     441        gfx_rect_t drect;
     442        gfx_rect_t skfbrect;
     443        gfx_rect_t crect;
     444        gfx_coord2_t offs;
     445        gfx_coord2_t bmdim;
     446        gfx_coord2_t dim;
     447        gfx_coord2_t sp;
     448        gfx_coord2_t dp;
     449        gfx_coord2_t pos;
     450        pixelmap_t pbm;
     451        pixel_t color;
     452
     453        /* Clip source rectangle to bitmap bounds */
     454
     455        if (srect0 != NULL)
     456                gfx_rect_clip(srect0, &dcbm->rect, &srect);
     457        else
     458                srect = dcbm->rect;
     459
     460        if (offs0 != NULL) {
     461                offs = *offs0;
     462        } else {
     463                offs.x = 0;
     464                offs.y = 0;
     465        }
     466
     467        /* Destination rectangle */
     468        gfx_rect_translate(&offs, &srect, &drect);
     469        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     470        gfx_coord2_subtract(&dcbm->rect.p1, &dcbm->rect.p0, &bmdim);
     471
     472        pbm.width = bmdim.x;
     473        pbm.height = bmdim.y;
     474        pbm.data = dcbm->alloc.pixels;
     475
     476        /* Transform AMDM37x bounding rectangle back to bitmap coordinate system */
     477        gfx_rect_rtranslate(&offs, &dispc->rect, &skfbrect);
     478
     479        /*
     480         * Make sure we have a sorted source rectangle, clipped so that
     481         * destination lies within AMDM37x bounding rectangle
     482         */
     483        gfx_rect_clip(&srect, &skfbrect, &crect);
     484
     485        for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
     486                for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
     487                        gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
     488                        gfx_coord2_add(&pos, &offs, &dp);
     489
     490                        color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
     491                        dispc->active_fb.pixel2visual(dispc->fb_data +
     492                            FB_POS(dispc, dp.x, dp.y), color);
    340493                }
    341494        }
    342495
     496        return EOK;
     497}
     498
     499/** Get allocation info for bitmap in AMDM37x GC.
     500 *
     501 * @param bm Bitmap
     502 * @param alloc Place to store allocation info
     503 * @return EOK on success or an error code
     504 */
     505static errno_t amdm37x_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     506{
     507        amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
     508        *alloc = dcbm->alloc;
    343509        return EOK;
    344510}
Note: See TracChangeset for help on using the changeset viewer.