Changeset 2a515dcd in mainline
- Timestamp:
- 2020-02-25T10:47:32Z (5 years ago)
- 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)
- Location:
- uspace/drv/fb/amdm37x_dispc
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c
r265989d r2a515dcd 1 1 /* 2 * Copyright (c) 2020 Jiri Svoboda 2 3 * Copyright (c) 2013 Jan Vesely 3 4 * All rights reserved. … … 35 36 36 37 #include <align.h> 38 #include <as.h> 37 39 #include <assert.h> 38 40 #include <errno.h> 41 #include <ddev_srv.h> 42 #include <ddev/info.h> 43 #include <ddf/driver.h> 39 44 #include <ddf/log.h> 40 45 #include <ddi.h> 41 #include <as.h> 46 #include <gfx/color.h> 47 #include <io/pixelmap.h> 42 48 43 49 #include "amdm37x_dispc.h" … … 55 61 #endif 56 62 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, 63 static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned, 64 visual_t); 65 66 static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *); 67 static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *); 68 69 static errno_t amdm37x_gc_set_color(void *, gfx_color_t *); 70 static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *); 71 static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *, 72 gfx_bitmap_alloc_t *, void **); 73 static errno_t amdm37x_gc_bitmap_destroy(void *); 74 static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *); 75 static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *); 76 77 ddev_ops_t amdm37x_ddev_ops = { 78 .get_gc = amdm37x_ddev_get_gc, 79 .get_info = amdm37x_ddev_get_info 80 }; 81 82 gfx_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 73 89 }; 74 90 … … 94 110 }; 95 111 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 112 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun) 113 { 114 instance->fun = fun; 119 115 instance->fb_data = NULL; 120 116 instance->size = 0; … … 145 141 } 146 142 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; 155 147 156 148 return EOK; … … 269 261 } 270 262 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; 263 static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x, 264 unsigned y, visual_t visual) 265 { 278 266 assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0])); 279 267 const unsigned bpp = pixel2visual_table[visual].bpp; 280 268 pixel2visual_t p2v = pixel2visual_table[visual].func; 281 const unsigned x = mode.screen_width;282 const unsigned y = mode.screen_height;283 269 ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8); 284 270 const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE); … … 296 282 dispc->fb_data = buffer; 297 283 amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa); 298 dispc->active_fb.idx = mode.index;299 284 dispc->active_fb.width = x; 300 285 dispc->active_fb.height = y; … … 302 287 dispc->active_fb.bpp = bpp; 303 288 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; 304 293 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 302 static 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 311 static 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 */ 332 static 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 */ 349 static 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 */ 376 errno_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(¶ms->rect.p1, ¶ms->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; 330 400 } 331 401 } 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; 408 error: 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 */ 419 static 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 */ 435 static 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); 340 493 } 341 494 } 342 495 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 */ 505 static 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; 343 509 return EOK; 344 510 } -
uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h
r265989d r2a515dcd 1 1 /* 2 * Copyright (c) 2020 Jiri Svoboda 2 3 * Copyright (c) 2013 Jan Vesely 3 4 * All rights reserved. … … 37 38 #define AMDM37X_DISPC_H_ 38 39 39 #include <graph.h>40 40 #include <abi/fb/visuals.h> 41 #include <ddev_srv.h> 42 #include <ddf/driver.h> 43 #include <gfx/context.h> 44 #include <gfx/coord.h> 45 #include <io/pixel.h> 41 46 #include <pixconv.h> 42 47 #include <ddi.h> … … 45 50 46 51 typedef struct { 52 ddf_fun_t *fun; 47 53 amdm37x_dispc_regs_t *regs; 48 54 … … 53 59 unsigned pitch; 54 60 unsigned bpp; 55 unsigned idx;56 61 } active_fb; 57 62 63 pixel_t color; 64 gfx_rect_t rect; 58 65 size_t size; 59 66 void *fb_data; 60 61 vslmode_list_element_t modes[1];62 67 } amdm37x_dispc_t; 63 68 64 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis); 65 errno_t amdm37x_dispc_fini(amdm37x_dispc_t *instance); 69 typedef struct { 70 amdm37x_dispc_t *dispc; 71 gfx_bitmap_alloc_t alloc; 72 gfx_rect_t rect; 73 bool myalloc; 74 } amdm37x_bitmap_t; 75 76 extern ddev_ops_t amdm37x_ddev_ops; 77 extern gfx_context_ops_t amdm37x_gc_ops; 78 79 extern errno_t amdm37x_dispc_init(amdm37x_dispc_t *, ddf_fun_t *); 80 extern errno_t amdm37x_dispc_fini(amdm37x_dispc_t *); 66 81 67 82 #endif -
uspace/drv/fb/amdm37x_dispc/main.c
r265989d r2a515dcd 1 1 /* 2 * Copyright (c) 2020 Jiri Svoboda 2 3 * Copyright (c) 2013 Jan Vesely 3 4 * Copyright (c) 2011 Petr Koupy … … 35 36 */ 36 37 38 #include <ddev_srv.h> 37 39 #include <ddf/driver.h> 38 40 #include <ddf/log.h> 39 41 #include <errno.h> 42 #include <ipcgfx/server.h> 40 43 #include <str_error.h> 41 44 #include <stdio.h> 42 #include <graph.h>43 45 44 46 #include "amdm37x_dispc.h" … … 46 48 #define NAME "amdm37x_dispc" 47 49 48 static void graph_vsl_connection(ipc_call_t *icall, void *arg)50 static void amdm37x_client_conn(ipc_call_t *icall, void *arg) 49 51 { 50 visualizer_t *vsl; 52 amdm37x_dispc_t *dispc; 53 ddev_srv_t srv; 54 sysarg_t gc_id; 55 gfx_context_t *gc; 56 errno_t rc; 51 57 52 vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg); 53 graph_visualizer_connection(vsl, icall, NULL); 58 dispc = (amdm37x_dispc_t *) ddf_dev_data_get( 59 ddf_fun_get_dev((ddf_fun_t *) arg)); 60 61 gc_id = ipc_get_arg3(icall); 62 63 if (gc_id == 0) { 64 /* Set up protocol structure */ 65 ddev_srv_initialize(&srv); 66 srv.ops = &amdm37x_ddev_ops; 67 srv.arg = dispc; 68 69 /* Handle connection */ 70 ddev_conn(icall, &srv); 71 } else { 72 assert(gc_id == 42); 73 74 rc = gfx_context_new(&amdm37x_gc_ops, dispc, &gc); 75 if (rc != EOK) 76 goto error; 77 78 /* GC connection */ 79 gc_conn(icall, gc); 80 } 81 82 return; 83 error: 84 async_answer_0(icall, rc); 54 85 } 55 86 … … 57 88 { 58 89 assert(dev); 59 /* Visualizer part */ 60 ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, " viz");90 91 ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "a"); 61 92 if (!fun) { 62 93 ddf_log_error("Failed to create visualizer function."); … … 64 95 } 65 96 66 visualizer_t *vis = ddf_fun_data_alloc(fun, sizeof(visualizer_t)); 67 if (!vis) { 68 ddf_log_error("Failed to allocate visualizer structure."); 69 ddf_fun_destroy(fun); 70 return ENOMEM; 71 } 97 ddf_fun_set_conn_handler(fun, &amdm37x_client_conn); 72 98 73 graph_init_visualizer(vis);74 vis->reg_svc_handle = ddf_fun_get_handle(fun);75 76 ddf_fun_set_conn_handler(fun, graph_vsl_connection);77 99 /* Hw part */ 78 100 amdm37x_dispc_t *dispc = … … 84 106 } 85 107 86 errno_t rc = amdm37x_dispc_init(dispc, vis);108 errno_t rc = amdm37x_dispc_init(dispc, fun); 87 109 if (rc != EOK) { 88 110 ddf_log_error("Failed to init dispc: %s.", str_error(rc)); … … 100 122 } 101 123 102 rc = ddf_fun_add_to_category(fun, " visualizer");124 rc = ddf_fun_add_to_category(fun, "display-device"); 103 125 if (rc != EOK) { 104 126 ddf_log_error("Failed to add function: %s to visualizer " -
uspace/drv/fb/amdm37x_dispc/meson.build
r265989d r2a515dcd 29 29 # 30 30 31 deps = [ 'g raph', 'softrend' ]31 deps = [ 'gfx', 'ipcgfx', 'ddev', 'softrend' ] 32 32 src = files('amdm37x_dispc.c', 'main.c')
Note:
See TracChangeset
for help on using the changeset viewer.