simpledrm.c (24326B)
1// SPDX-License-Identifier: GPL-2.0-only 2 3#include <linux/clk.h> 4#include <linux/of_clk.h> 5#include <linux/minmax.h> 6#include <linux/platform_data/simplefb.h> 7#include <linux/platform_device.h> 8#include <linux/regulator/consumer.h> 9 10#include <drm/drm_aperture.h> 11#include <drm/drm_atomic_state_helper.h> 12#include <drm/drm_connector.h> 13#include <drm/drm_damage_helper.h> 14#include <drm/drm_device.h> 15#include <drm/drm_drv.h> 16#include <drm/drm_fb_helper.h> 17#include <drm/drm_format_helper.h> 18#include <drm/drm_gem_atomic_helper.h> 19#include <drm/drm_gem_framebuffer_helper.h> 20#include <drm/drm_gem_shmem_helper.h> 21#include <drm/drm_managed.h> 22#include <drm/drm_modeset_helper_vtables.h> 23#include <drm/drm_probe_helper.h> 24#include <drm/drm_simple_kms_helper.h> 25 26#define DRIVER_NAME "simpledrm" 27#define DRIVER_DESC "DRM driver for simple-framebuffer platform devices" 28#define DRIVER_DATE "20200625" 29#define DRIVER_MAJOR 1 30#define DRIVER_MINOR 0 31 32/* 33 * Assume a monitor resolution of 96 dpi to 34 * get a somewhat reasonable screen size. 35 */ 36#define RES_MM(d) \ 37 (((d) * 254ul) / (96ul * 10ul)) 38 39#define SIMPLEDRM_MODE(hd, vd) \ 40 DRM_SIMPLE_MODE(hd, vd, RES_MM(hd), RES_MM(vd)) 41 42/* 43 * Helpers for simplefb 44 */ 45 46static int 47simplefb_get_validated_int(struct drm_device *dev, const char *name, 48 uint32_t value) 49{ 50 if (value > INT_MAX) { 51 drm_err(dev, "simplefb: invalid framebuffer %s of %u\n", 52 name, value); 53 return -EINVAL; 54 } 55 return (int)value; 56} 57 58static int 59simplefb_get_validated_int0(struct drm_device *dev, const char *name, 60 uint32_t value) 61{ 62 if (!value) { 63 drm_err(dev, "simplefb: invalid framebuffer %s of %u\n", 64 name, value); 65 return -EINVAL; 66 } 67 return simplefb_get_validated_int(dev, name, value); 68} 69 70static const struct drm_format_info * 71simplefb_get_validated_format(struct drm_device *dev, const char *format_name) 72{ 73 static const struct simplefb_format formats[] = SIMPLEFB_FORMATS; 74 const struct simplefb_format *fmt = formats; 75 const struct simplefb_format *end = fmt + ARRAY_SIZE(formats); 76 const struct drm_format_info *info; 77 78 if (!format_name) { 79 drm_err(dev, "simplefb: missing framebuffer format\n"); 80 return ERR_PTR(-EINVAL); 81 } 82 83 while (fmt < end) { 84 if (!strcmp(format_name, fmt->name)) { 85 info = drm_format_info(fmt->fourcc); 86 if (!info) 87 return ERR_PTR(-EINVAL); 88 return info; 89 } 90 ++fmt; 91 } 92 93 drm_err(dev, "simplefb: unknown framebuffer format %s\n", 94 format_name); 95 96 return ERR_PTR(-EINVAL); 97} 98 99static int 100simplefb_get_width_pd(struct drm_device *dev, 101 const struct simplefb_platform_data *pd) 102{ 103 return simplefb_get_validated_int0(dev, "width", pd->width); 104} 105 106static int 107simplefb_get_height_pd(struct drm_device *dev, 108 const struct simplefb_platform_data *pd) 109{ 110 return simplefb_get_validated_int0(dev, "height", pd->height); 111} 112 113static int 114simplefb_get_stride_pd(struct drm_device *dev, 115 const struct simplefb_platform_data *pd) 116{ 117 return simplefb_get_validated_int(dev, "stride", pd->stride); 118} 119 120static const struct drm_format_info * 121simplefb_get_format_pd(struct drm_device *dev, 122 const struct simplefb_platform_data *pd) 123{ 124 return simplefb_get_validated_format(dev, pd->format); 125} 126 127static int 128simplefb_read_u32_of(struct drm_device *dev, struct device_node *of_node, 129 const char *name, u32 *value) 130{ 131 int ret = of_property_read_u32(of_node, name, value); 132 133 if (ret) 134 drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n", 135 name, ret); 136 return ret; 137} 138 139static int 140simplefb_read_string_of(struct drm_device *dev, struct device_node *of_node, 141 const char *name, const char **value) 142{ 143 int ret = of_property_read_string(of_node, name, value); 144 145 if (ret) 146 drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n", 147 name, ret); 148 return ret; 149} 150 151static int 152simplefb_get_width_of(struct drm_device *dev, struct device_node *of_node) 153{ 154 u32 width; 155 int ret = simplefb_read_u32_of(dev, of_node, "width", &width); 156 157 if (ret) 158 return ret; 159 return simplefb_get_validated_int0(dev, "width", width); 160} 161 162static int 163simplefb_get_height_of(struct drm_device *dev, struct device_node *of_node) 164{ 165 u32 height; 166 int ret = simplefb_read_u32_of(dev, of_node, "height", &height); 167 168 if (ret) 169 return ret; 170 return simplefb_get_validated_int0(dev, "height", height); 171} 172 173static int 174simplefb_get_stride_of(struct drm_device *dev, struct device_node *of_node) 175{ 176 u32 stride; 177 int ret = simplefb_read_u32_of(dev, of_node, "stride", &stride); 178 179 if (ret) 180 return ret; 181 return simplefb_get_validated_int(dev, "stride", stride); 182} 183 184static const struct drm_format_info * 185simplefb_get_format_of(struct drm_device *dev, struct device_node *of_node) 186{ 187 const char *format; 188 int ret = simplefb_read_string_of(dev, of_node, "format", &format); 189 190 if (ret) 191 return ERR_PTR(ret); 192 return simplefb_get_validated_format(dev, format); 193} 194 195/* 196 * Simple Framebuffer device 197 */ 198 199struct simpledrm_device { 200 struct drm_device dev; 201 struct platform_device *pdev; 202 203 /* clocks */ 204#if defined CONFIG_OF && defined CONFIG_COMMON_CLK 205 unsigned int clk_count; 206 struct clk **clks; 207#endif 208 /* regulators */ 209#if defined CONFIG_OF && defined CONFIG_REGULATOR 210 unsigned int regulator_count; 211 struct regulator **regulators; 212#endif 213 214 /* simplefb settings */ 215 struct drm_display_mode mode; 216 const struct drm_format_info *format; 217 unsigned int pitch; 218 219 /* memory management */ 220 struct resource *mem; 221 void __iomem *screen_base; 222 223 /* modesetting */ 224 uint32_t formats[8]; 225 size_t nformats; 226 struct drm_connector connector; 227 struct drm_simple_display_pipe pipe; 228}; 229 230static struct simpledrm_device *simpledrm_device_of_dev(struct drm_device *dev) 231{ 232 return container_of(dev, struct simpledrm_device, dev); 233} 234 235/* 236 * Hardware 237 */ 238 239#if defined CONFIG_OF && defined CONFIG_COMMON_CLK 240/* 241 * Clock handling code. 242 * 243 * Here we handle the clocks property of our "simple-framebuffer" dt node. 244 * This is necessary so that we can make sure that any clocks needed by 245 * the display engine that the bootloader set up for us (and for which it 246 * provided a simplefb dt node), stay up, for the life of the simplefb 247 * driver. 248 * 249 * When the driver unloads, we cleanly disable, and then release the clocks. 250 * 251 * We only complain about errors here, no action is taken as the most likely 252 * error can only happen due to a mismatch between the bootloader which set 253 * up simplefb, and the clock definitions in the device tree. Chances are 254 * that there are no adverse effects, and if there are, a clean teardown of 255 * the fb probe will not help us much either. So just complain and carry on, 256 * and hope that the user actually gets a working fb at the end of things. 257 */ 258 259static void simpledrm_device_release_clocks(void *res) 260{ 261 struct simpledrm_device *sdev = simpledrm_device_of_dev(res); 262 unsigned int i; 263 264 for (i = 0; i < sdev->clk_count; ++i) { 265 if (sdev->clks[i]) { 266 clk_disable_unprepare(sdev->clks[i]); 267 clk_put(sdev->clks[i]); 268 } 269 } 270} 271 272static int simpledrm_device_init_clocks(struct simpledrm_device *sdev) 273{ 274 struct drm_device *dev = &sdev->dev; 275 struct platform_device *pdev = sdev->pdev; 276 struct device_node *of_node = pdev->dev.of_node; 277 struct clk *clock; 278 unsigned int i; 279 int ret; 280 281 if (dev_get_platdata(&pdev->dev) || !of_node) 282 return 0; 283 284 sdev->clk_count = of_clk_get_parent_count(of_node); 285 if (!sdev->clk_count) 286 return 0; 287 288 sdev->clks = drmm_kzalloc(dev, sdev->clk_count * sizeof(sdev->clks[0]), 289 GFP_KERNEL); 290 if (!sdev->clks) 291 return -ENOMEM; 292 293 for (i = 0; i < sdev->clk_count; ++i) { 294 clock = of_clk_get(of_node, i); 295 if (IS_ERR(clock)) { 296 ret = PTR_ERR(clock); 297 if (ret == -EPROBE_DEFER) 298 goto err; 299 drm_err(dev, "clock %u not found: %d\n", i, ret); 300 continue; 301 } 302 ret = clk_prepare_enable(clock); 303 if (ret) { 304 drm_err(dev, "failed to enable clock %u: %d\n", 305 i, ret); 306 clk_put(clock); 307 continue; 308 } 309 sdev->clks[i] = clock; 310 } 311 312 return devm_add_action_or_reset(&pdev->dev, 313 simpledrm_device_release_clocks, 314 sdev); 315 316err: 317 while (i) { 318 --i; 319 if (sdev->clks[i]) { 320 clk_disable_unprepare(sdev->clks[i]); 321 clk_put(sdev->clks[i]); 322 } 323 } 324 return ret; 325} 326#else 327static int simpledrm_device_init_clocks(struct simpledrm_device *sdev) 328{ 329 return 0; 330} 331#endif 332 333#if defined CONFIG_OF && defined CONFIG_REGULATOR 334 335#define SUPPLY_SUFFIX "-supply" 336 337/* 338 * Regulator handling code. 339 * 340 * Here we handle the num-supplies and vin*-supply properties of our 341 * "simple-framebuffer" dt node. This is necessary so that we can make sure 342 * that any regulators needed by the display hardware that the bootloader 343 * set up for us (and for which it provided a simplefb dt node), stay up, 344 * for the life of the simplefb driver. 345 * 346 * When the driver unloads, we cleanly disable, and then release the 347 * regulators. 348 * 349 * We only complain about errors here, no action is taken as the most likely 350 * error can only happen due to a mismatch between the bootloader which set 351 * up simplefb, and the regulator definitions in the device tree. Chances are 352 * that there are no adverse effects, and if there are, a clean teardown of 353 * the fb probe will not help us much either. So just complain and carry on, 354 * and hope that the user actually gets a working fb at the end of things. 355 */ 356 357static void simpledrm_device_release_regulators(void *res) 358{ 359 struct simpledrm_device *sdev = simpledrm_device_of_dev(res); 360 unsigned int i; 361 362 for (i = 0; i < sdev->regulator_count; ++i) { 363 if (sdev->regulators[i]) { 364 regulator_disable(sdev->regulators[i]); 365 regulator_put(sdev->regulators[i]); 366 } 367 } 368} 369 370static int simpledrm_device_init_regulators(struct simpledrm_device *sdev) 371{ 372 struct drm_device *dev = &sdev->dev; 373 struct platform_device *pdev = sdev->pdev; 374 struct device_node *of_node = pdev->dev.of_node; 375 struct property *prop; 376 struct regulator *regulator; 377 const char *p; 378 unsigned int count = 0, i = 0; 379 int ret; 380 381 if (dev_get_platdata(&pdev->dev) || !of_node) 382 return 0; 383 384 /* Count the number of regulator supplies */ 385 for_each_property_of_node(of_node, prop) { 386 p = strstr(prop->name, SUPPLY_SUFFIX); 387 if (p && p != prop->name) 388 ++count; 389 } 390 391 if (!count) 392 return 0; 393 394 sdev->regulators = drmm_kzalloc(dev, 395 count * sizeof(sdev->regulators[0]), 396 GFP_KERNEL); 397 if (!sdev->regulators) 398 return -ENOMEM; 399 400 for_each_property_of_node(of_node, prop) { 401 char name[32]; /* 32 is max size of property name */ 402 size_t len; 403 404 p = strstr(prop->name, SUPPLY_SUFFIX); 405 if (!p || p == prop->name) 406 continue; 407 len = strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1; 408 strscpy(name, prop->name, min(sizeof(name), len)); 409 410 regulator = regulator_get_optional(&pdev->dev, name); 411 if (IS_ERR(regulator)) { 412 ret = PTR_ERR(regulator); 413 if (ret == -EPROBE_DEFER) 414 goto err; 415 drm_err(dev, "regulator %s not found: %d\n", 416 name, ret); 417 continue; 418 } 419 420 ret = regulator_enable(regulator); 421 if (ret) { 422 drm_err(dev, "failed to enable regulator %u: %d\n", 423 i, ret); 424 regulator_put(regulator); 425 continue; 426 } 427 428 sdev->regulators[i++] = regulator; 429 } 430 sdev->regulator_count = i; 431 432 return devm_add_action_or_reset(&pdev->dev, 433 simpledrm_device_release_regulators, 434 sdev); 435 436err: 437 while (i) { 438 --i; 439 if (sdev->regulators[i]) { 440 regulator_disable(sdev->regulators[i]); 441 regulator_put(sdev->regulators[i]); 442 } 443 } 444 return ret; 445} 446#else 447static int simpledrm_device_init_regulators(struct simpledrm_device *sdev) 448{ 449 return 0; 450} 451#endif 452 453/* 454 * Simplefb settings 455 */ 456 457static struct drm_display_mode simpledrm_mode(unsigned int width, 458 unsigned int height) 459{ 460 struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) }; 461 462 mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */; 463 drm_mode_set_name(&mode); 464 465 return mode; 466} 467 468static int simpledrm_device_init_fb(struct simpledrm_device *sdev) 469{ 470 int width, height, stride; 471 const struct drm_format_info *format; 472 struct drm_device *dev = &sdev->dev; 473 struct platform_device *pdev = sdev->pdev; 474 const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev); 475 struct device_node *of_node = pdev->dev.of_node; 476 477 if (pd) { 478 width = simplefb_get_width_pd(dev, pd); 479 if (width < 0) 480 return width; 481 height = simplefb_get_height_pd(dev, pd); 482 if (height < 0) 483 return height; 484 stride = simplefb_get_stride_pd(dev, pd); 485 if (stride < 0) 486 return stride; 487 format = simplefb_get_format_pd(dev, pd); 488 if (IS_ERR(format)) 489 return PTR_ERR(format); 490 } else if (of_node) { 491 width = simplefb_get_width_of(dev, of_node); 492 if (width < 0) 493 return width; 494 height = simplefb_get_height_of(dev, of_node); 495 if (height < 0) 496 return height; 497 stride = simplefb_get_stride_of(dev, of_node); 498 if (stride < 0) 499 return stride; 500 format = simplefb_get_format_of(dev, of_node); 501 if (IS_ERR(format)) 502 return PTR_ERR(format); 503 } else { 504 drm_err(dev, "no simplefb configuration found\n"); 505 return -ENODEV; 506 } 507 508 sdev->mode = simpledrm_mode(width, height); 509 sdev->format = format; 510 sdev->pitch = stride; 511 512 drm_dbg_kms(dev, "display mode={" DRM_MODE_FMT "}\n", 513 DRM_MODE_ARG(&sdev->mode)); 514 drm_dbg_kms(dev, 515 "framebuffer format=%p4cc, size=%dx%d, stride=%d byte\n", 516 &format->format, width, height, stride); 517 518 return 0; 519} 520 521/* 522 * Memory management 523 */ 524 525static int simpledrm_device_init_mm(struct simpledrm_device *sdev) 526{ 527 struct drm_device *dev = &sdev->dev; 528 struct platform_device *pdev = sdev->pdev; 529 struct resource *res, *mem; 530 void __iomem *screen_base; 531 int ret; 532 533 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 534 if (!res) 535 return -EINVAL; 536 537 ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res)); 538 if (ret) { 539 drm_err(dev, "could not acquire memory range %pr: error %d\n", 540 res, ret); 541 return ret; 542 } 543 544 mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res), 545 sdev->dev.driver->name); 546 if (!mem) { 547 /* 548 * We cannot make this fatal. Sometimes this comes from magic 549 * spaces our resource handlers simply don't know about. Use 550 * the I/O-memory resource as-is and try to map that instead. 551 */ 552 drm_warn(dev, "could not acquire memory region %pr\n", res); 553 mem = res; 554 } 555 556 screen_base = devm_ioremap_wc(&pdev->dev, mem->start, 557 resource_size(mem)); 558 if (!screen_base) 559 return -ENOMEM; 560 561 sdev->mem = mem; 562 sdev->screen_base = screen_base; 563 564 return 0; 565} 566 567/* 568 * Modesetting 569 */ 570 571/* 572 * Support all formats of simplefb and maybe more; in order 573 * of preference. The display's update function will do any 574 * conversion necessary. 575 * 576 * TODO: Add blit helpers for remaining formats and uncomment 577 * constants. 578 */ 579static const uint32_t simpledrm_default_formats[] = { 580 DRM_FORMAT_XRGB8888, 581 DRM_FORMAT_ARGB8888, 582 DRM_FORMAT_RGB565, 583 //DRM_FORMAT_XRGB1555, 584 //DRM_FORMAT_ARGB1555, 585 DRM_FORMAT_RGB888, 586 DRM_FORMAT_XRGB2101010, 587 DRM_FORMAT_ARGB2101010, 588}; 589 590static const uint64_t simpledrm_format_modifiers[] = { 591 DRM_FORMAT_MOD_LINEAR, 592 DRM_FORMAT_MOD_INVALID 593}; 594 595static int simpledrm_connector_helper_get_modes(struct drm_connector *connector) 596{ 597 struct simpledrm_device *sdev = simpledrm_device_of_dev(connector->dev); 598 struct drm_display_mode *mode; 599 600 mode = drm_mode_duplicate(connector->dev, &sdev->mode); 601 if (!mode) 602 return 0; 603 604 if (mode->name[0] == '\0') 605 drm_mode_set_name(mode); 606 607 mode->type |= DRM_MODE_TYPE_PREFERRED; 608 drm_mode_probed_add(connector, mode); 609 610 if (mode->width_mm) 611 connector->display_info.width_mm = mode->width_mm; 612 if (mode->height_mm) 613 connector->display_info.height_mm = mode->height_mm; 614 615 return 1; 616} 617 618static const struct drm_connector_helper_funcs simpledrm_connector_helper_funcs = { 619 .get_modes = simpledrm_connector_helper_get_modes, 620}; 621 622static const struct drm_connector_funcs simpledrm_connector_funcs = { 623 .reset = drm_atomic_helper_connector_reset, 624 .fill_modes = drm_helper_probe_single_connector_modes, 625 .destroy = drm_connector_cleanup, 626 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 627 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 628}; 629 630static int 631simpledrm_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe, 632 const struct drm_display_mode *mode) 633{ 634 struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); 635 636 if (mode->hdisplay != sdev->mode.hdisplay && 637 mode->vdisplay != sdev->mode.vdisplay) 638 return MODE_ONE_SIZE; 639 else if (mode->hdisplay != sdev->mode.hdisplay) 640 return MODE_ONE_WIDTH; 641 else if (mode->vdisplay != sdev->mode.vdisplay) 642 return MODE_ONE_HEIGHT; 643 644 return MODE_OK; 645} 646 647static void 648simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, 649 struct drm_crtc_state *crtc_state, 650 struct drm_plane_state *plane_state) 651{ 652 struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); 653 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); 654 struct drm_framebuffer *fb = plane_state->fb; 655 void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */ 656 struct drm_device *dev = &sdev->dev; 657 void __iomem *dst = sdev->screen_base; 658 struct drm_rect src_clip, dst_clip; 659 int idx; 660 661 if (!fb) 662 return; 663 664 drm_rect_fp_to_int(&src_clip, &plane_state->src); 665 666 dst_clip = plane_state->dst; 667 if (!drm_rect_intersect(&dst_clip, &src_clip)) 668 return; 669 670 if (!drm_dev_enter(dev, &idx)) 671 return; 672 673 dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip); 674 drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip); 675 676 drm_dev_exit(idx); 677} 678 679static void 680simpledrm_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe) 681{ 682 struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); 683 struct drm_device *dev = &sdev->dev; 684 int idx; 685 686 if (!drm_dev_enter(dev, &idx)) 687 return; 688 689 /* Clear screen to black if disabled */ 690 memset_io(sdev->screen_base, 0, sdev->pitch * sdev->mode.vdisplay); 691 692 drm_dev_exit(idx); 693} 694 695static void 696simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, 697 struct drm_plane_state *old_plane_state) 698{ 699 struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev); 700 struct drm_plane_state *plane_state = pipe->plane.state; 701 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); 702 void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */ 703 struct drm_framebuffer *fb = plane_state->fb; 704 struct drm_device *dev = &sdev->dev; 705 void __iomem *dst = sdev->screen_base; 706 struct drm_rect src_clip, dst_clip; 707 int idx; 708 709 if (!fb) 710 return; 711 712 if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip)) 713 return; 714 715 dst_clip = plane_state->dst; 716 if (!drm_rect_intersect(&dst_clip, &src_clip)) 717 return; 718 719 if (!drm_dev_enter(dev, &idx)) 720 return; 721 722 dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip); 723 drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip); 724 725 drm_dev_exit(idx); 726} 727 728static const struct drm_simple_display_pipe_funcs 729simpledrm_simple_display_pipe_funcs = { 730 .mode_valid = simpledrm_simple_display_pipe_mode_valid, 731 .enable = simpledrm_simple_display_pipe_enable, 732 .disable = simpledrm_simple_display_pipe_disable, 733 .update = simpledrm_simple_display_pipe_update, 734 DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, 735}; 736 737static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = { 738 .fb_create = drm_gem_fb_create_with_dirty, 739 .atomic_check = drm_atomic_helper_check, 740 .atomic_commit = drm_atomic_helper_commit, 741}; 742 743static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev, 744 size_t *nformats_out) 745{ 746 struct drm_device *dev = &sdev->dev; 747 size_t i; 748 749 if (sdev->nformats) 750 goto out; /* don't rebuild list on recurring calls */ 751 752 /* native format goes first */ 753 sdev->formats[0] = sdev->format->format; 754 sdev->nformats = 1; 755 756 /* default formats go second */ 757 for (i = 0; i < ARRAY_SIZE(simpledrm_default_formats); ++i) { 758 if (simpledrm_default_formats[i] == sdev->format->format) 759 continue; /* native format already went first */ 760 sdev->formats[sdev->nformats] = simpledrm_default_formats[i]; 761 sdev->nformats++; 762 } 763 764 /* 765 * TODO: The simpledrm driver converts framebuffers to the native 766 * format when copying them to device memory. If there are more 767 * formats listed than supported by the driver, the native format 768 * is not supported by the conversion helpers. Therefore *only* 769 * support the native format and add a conversion helper ASAP. 770 */ 771 if (drm_WARN_ONCE(dev, i != sdev->nformats, 772 "format conversion helpers required for %p4cc", 773 &sdev->format->format)) { 774 sdev->nformats = 1; 775 } 776 777out: 778 *nformats_out = sdev->nformats; 779 return sdev->formats; 780} 781 782static int simpledrm_device_init_modeset(struct simpledrm_device *sdev) 783{ 784 struct drm_device *dev = &sdev->dev; 785 struct drm_display_mode *mode = &sdev->mode; 786 struct drm_connector *connector = &sdev->connector; 787 struct drm_simple_display_pipe *pipe = &sdev->pipe; 788 unsigned long max_width, max_height; 789 const uint32_t *formats; 790 size_t nformats; 791 int ret; 792 793 ret = drmm_mode_config_init(dev); 794 if (ret) 795 return ret; 796 797 max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH); 798 max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT); 799 800 dev->mode_config.min_width = mode->hdisplay; 801 dev->mode_config.max_width = max_width; 802 dev->mode_config.min_height = mode->vdisplay; 803 dev->mode_config.max_height = max_height; 804 dev->mode_config.preferred_depth = sdev->format->cpp[0] * 8; 805 dev->mode_config.funcs = &simpledrm_mode_config_funcs; 806 807 ret = drm_connector_init(dev, connector, &simpledrm_connector_funcs, 808 DRM_MODE_CONNECTOR_Unknown); 809 if (ret) 810 return ret; 811 drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs); 812 drm_connector_set_panel_orientation_with_quirk(connector, 813 DRM_MODE_PANEL_ORIENTATION_UNKNOWN, 814 mode->hdisplay, mode->vdisplay); 815 816 formats = simpledrm_device_formats(sdev, &nformats); 817 818 ret = drm_simple_display_pipe_init(dev, pipe, &simpledrm_simple_display_pipe_funcs, 819 formats, nformats, simpledrm_format_modifiers, 820 connector); 821 if (ret) 822 return ret; 823 824 drm_plane_enable_fb_damage_clips(&pipe->plane); 825 826 drm_mode_config_reset(dev); 827 828 return 0; 829} 830 831/* 832 * Init / Cleanup 833 */ 834 835static struct simpledrm_device * 836simpledrm_device_create(struct drm_driver *drv, struct platform_device *pdev) 837{ 838 struct simpledrm_device *sdev; 839 int ret; 840 841 sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device, 842 dev); 843 if (IS_ERR(sdev)) 844 return ERR_CAST(sdev); 845 sdev->pdev = pdev; 846 platform_set_drvdata(pdev, sdev); 847 848 ret = simpledrm_device_init_clocks(sdev); 849 if (ret) 850 return ERR_PTR(ret); 851 ret = simpledrm_device_init_regulators(sdev); 852 if (ret) 853 return ERR_PTR(ret); 854 ret = simpledrm_device_init_fb(sdev); 855 if (ret) 856 return ERR_PTR(ret); 857 ret = simpledrm_device_init_mm(sdev); 858 if (ret) 859 return ERR_PTR(ret); 860 ret = simpledrm_device_init_modeset(sdev); 861 if (ret) 862 return ERR_PTR(ret); 863 864 return sdev; 865} 866 867/* 868 * DRM driver 869 */ 870 871DEFINE_DRM_GEM_FOPS(simpledrm_fops); 872 873static struct drm_driver simpledrm_driver = { 874 DRM_GEM_SHMEM_DRIVER_OPS, 875 .name = DRIVER_NAME, 876 .desc = DRIVER_DESC, 877 .date = DRIVER_DATE, 878 .major = DRIVER_MAJOR, 879 .minor = DRIVER_MINOR, 880 .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, 881 .fops = &simpledrm_fops, 882}; 883 884/* 885 * Platform driver 886 */ 887 888static int simpledrm_probe(struct platform_device *pdev) 889{ 890 struct simpledrm_device *sdev; 891 struct drm_device *dev; 892 int ret; 893 894 sdev = simpledrm_device_create(&simpledrm_driver, pdev); 895 if (IS_ERR(sdev)) 896 return PTR_ERR(sdev); 897 dev = &sdev->dev; 898 899 ret = drm_dev_register(dev, 0); 900 if (ret) 901 return ret; 902 903 drm_fbdev_generic_setup(dev, 0); 904 905 return 0; 906} 907 908static int simpledrm_remove(struct platform_device *pdev) 909{ 910 struct simpledrm_device *sdev = platform_get_drvdata(pdev); 911 struct drm_device *dev = &sdev->dev; 912 913 drm_dev_unplug(dev); 914 915 return 0; 916} 917 918static const struct of_device_id simpledrm_of_match_table[] = { 919 { .compatible = "simple-framebuffer", }, 920 { }, 921}; 922MODULE_DEVICE_TABLE(of, simpledrm_of_match_table); 923 924static struct platform_driver simpledrm_platform_driver = { 925 .driver = { 926 .name = "simple-framebuffer", /* connect to sysfb */ 927 .of_match_table = simpledrm_of_match_table, 928 }, 929 .probe = simpledrm_probe, 930 .remove = simpledrm_remove, 931}; 932 933module_platform_driver(simpledrm_platform_driver); 934 935MODULE_DESCRIPTION(DRIVER_DESC); 936MODULE_LICENSE("GPL v2");