1 /* 2 * (C) COPYRIGHT 2016 ARM Limited. All rights reserved. 3 * Author: Liviu Dudau <Liviu.Dudau@arm.com> 4 * 5 * This program is free software and is provided to you under the terms of the 6 * GNU General Public License version 2 as published by the Free Software 7 * Foundation, and any use by you of this program is subject to the terms 8 * of such GNU licence. 9 * 10 * ARM Mali DP500/DP550/DP650 KMS/DRM driver 11 */ 12 13 #include <linux/module.h> 14 #include <linux/clk.h> 15 #include <linux/component.h> 16 #include <linux/of_device.h> 17 #include <linux/of_graph.h> 18 #include <linux/of_reserved_mem.h> 19 #include <linux/pm_runtime.h> 20 21 #include <drm/drmP.h> 22 #include <drm/drm_atomic.h> 23 #include <drm/drm_atomic_helper.h> 24 #include <drm/drm_crtc.h> 25 #include <drm/drm_crtc_helper.h> 26 #include <drm/drm_fb_helper.h> 27 #include <drm/drm_fb_cma_helper.h> 28 #include <drm/drm_gem_cma_helper.h> 29 #include <drm/drm_gem_framebuffer_helper.h> 30 #include <drm/drm_modeset_helper.h> 31 #include <drm/drm_of.h> 32 33 #include "malidp_drv.h" 34 #include "malidp_regs.h" 35 #include "malidp_hw.h" 36 37 #define MALIDP_CONF_VALID_TIMEOUT 250 38 39 static void malidp_write_gamma_table(struct malidp_hw_device *hwdev, 40 u32 data[MALIDP_COEFFTAB_NUM_COEFFS]) 41 { 42 int i; 43 /* Update all channels with a single gamma curve. */ 44 const u32 gamma_write_mask = GENMASK(18, 16); 45 /* 46 * Always write an entire table, so the address field in 47 * DE_COEFFTAB_ADDR is 0 and we can use the gamma_write_mask bitmask 48 * directly. 49 */ 50 malidp_hw_write(hwdev, gamma_write_mask, 51 hwdev->hw->map.coeffs_base + MALIDP_COEF_TABLE_ADDR); 52 for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i) 53 malidp_hw_write(hwdev, data[i], 54 hwdev->hw->map.coeffs_base + 55 MALIDP_COEF_TABLE_DATA); 56 } 57 58 static void malidp_atomic_commit_update_gamma(struct drm_crtc *crtc, 59 struct drm_crtc_state *old_state) 60 { 61 struct malidp_drm *malidp = crtc_to_malidp_device(crtc); 62 struct malidp_hw_device *hwdev = malidp->dev; 63 64 if (!crtc->state->color_mgmt_changed) 65 return; 66 67 if (!crtc->state->gamma_lut) { 68 malidp_hw_clearbits(hwdev, 69 MALIDP_DISP_FUNC_GAMMA, 70 MALIDP_DE_DISPLAY_FUNC); 71 } else { 72 struct malidp_crtc_state *mc = 73 to_malidp_crtc_state(crtc->state); 74 75 if (!old_state->gamma_lut || (crtc->state->gamma_lut->base.id != 76 old_state->gamma_lut->base.id)) 77 malidp_write_gamma_table(hwdev, mc->gamma_coeffs); 78 79 malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_GAMMA, 80 MALIDP_DE_DISPLAY_FUNC); 81 } 82 } 83 84 static 85 void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc, 86 struct drm_crtc_state *old_state) 87 { 88 struct malidp_drm *malidp = crtc_to_malidp_device(crtc); 89 struct malidp_hw_device *hwdev = malidp->dev; 90 int i; 91 92 if (!crtc->state->color_mgmt_changed) 93 return; 94 95 if (!crtc->state->ctm) { 96 malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_CADJ, 97 MALIDP_DE_DISPLAY_FUNC); 98 } else { 99 struct malidp_crtc_state *mc = 100 to_malidp_crtc_state(crtc->state); 101 102 if (!old_state->ctm || (crtc->state->ctm->base.id != 103 old_state->ctm->base.id)) 104 for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i) 105 malidp_hw_write(hwdev, 106 mc->coloradj_coeffs[i], 107 hwdev->hw->map.coeffs_base + 108 MALIDP_COLOR_ADJ_COEF + 4 * i); 109 110 malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ, 111 MALIDP_DE_DISPLAY_FUNC); 112 } 113 } 114 115 static void malidp_atomic_commit_se_config(struct drm_crtc *crtc, 116 struct drm_crtc_state *old_state) 117 { 118 struct malidp_crtc_state *cs = to_malidp_crtc_state(crtc->state); 119 struct malidp_crtc_state *old_cs = to_malidp_crtc_state(old_state); 120 struct malidp_drm *malidp = crtc_to_malidp_device(crtc); 121 struct malidp_hw_device *hwdev = malidp->dev; 122 struct malidp_se_config *s = &cs->scaler_config; 123 struct malidp_se_config *old_s = &old_cs->scaler_config; 124 u32 se_control = hwdev->hw->map.se_base + 125 ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ? 126 0x10 : 0xC); 127 u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL; 128 u32 scr = se_control + MALIDP_SE_SCALING_CONTROL; 129 u32 val; 130 131 /* Set SE_CONTROL */ 132 if (!s->scale_enable) { 133 val = malidp_hw_read(hwdev, se_control); 134 val &= ~MALIDP_SE_SCALING_EN; 135 malidp_hw_write(hwdev, val, se_control); 136 return; 137 } 138 139 hwdev->hw->se_set_scaling_coeffs(hwdev, s, old_s); 140 val = malidp_hw_read(hwdev, se_control); 141 val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN; 142 143 val &= ~MALIDP_SE_ENH(MALIDP_SE_ENH_MASK); 144 val |= s->enhancer_enable ? MALIDP_SE_ENH(3) : 0; 145 146 val |= MALIDP_SE_RGBO_IF_EN; 147 malidp_hw_write(hwdev, val, se_control); 148 149 /* Set IN_SIZE & OUT_SIZE. */ 150 val = MALIDP_SE_SET_V_SIZE(s->input_h) | 151 MALIDP_SE_SET_H_SIZE(s->input_w); 152 malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_IN_SIZE); 153 val = MALIDP_SE_SET_V_SIZE(s->output_h) | 154 MALIDP_SE_SET_H_SIZE(s->output_w); 155 malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_OUT_SIZE); 156 157 /* Set phase regs. */ 158 malidp_hw_write(hwdev, s->h_init_phase, scr + MALIDP_SE_H_INIT_PH); 159 malidp_hw_write(hwdev, s->h_delta_phase, scr + MALIDP_SE_H_DELTA_PH); 160 malidp_hw_write(hwdev, s->v_init_phase, scr + MALIDP_SE_V_INIT_PH); 161 malidp_hw_write(hwdev, s->v_delta_phase, scr + MALIDP_SE_V_DELTA_PH); 162 } 163 164 /* 165 * set the "config valid" bit and wait until the hardware acts on it 166 */ 167 static int malidp_set_and_wait_config_valid(struct drm_device *drm) 168 { 169 struct malidp_drm *malidp = drm->dev_private; 170 struct malidp_hw_device *hwdev = malidp->dev; 171 int ret; 172 173 atomic_set(&malidp->config_valid, 0); 174 hwdev->hw->set_config_valid(hwdev); 175 /* don't wait for config_valid flag if we are in config mode */ 176 if (hwdev->hw->in_config_mode(hwdev)) 177 return 0; 178 179 ret = wait_event_interruptible_timeout(malidp->wq, 180 atomic_read(&malidp->config_valid) == 1, 181 msecs_to_jiffies(MALIDP_CONF_VALID_TIMEOUT)); 182 183 return (ret > 0) ? 0 : -ETIMEDOUT; 184 } 185 186 static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state) 187 { 188 struct drm_device *drm = state->dev; 189 struct malidp_drm *malidp = drm->dev_private; 190 191 malidp->event = malidp->crtc.state->event; 192 malidp->crtc.state->event = NULL; 193 194 if (malidp->crtc.state->active) { 195 /* 196 * if we have an event to deliver to userspace, make sure 197 * the vblank is enabled as we are sending it from the IRQ 198 * handler. 199 */ 200 if (malidp->event) 201 drm_crtc_vblank_get(&malidp->crtc); 202 203 /* only set config_valid if the CRTC is enabled */ 204 if (malidp_set_and_wait_config_valid(drm) < 0) 205 DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n"); 206 } else if (malidp->event) { 207 /* CRTC inactive means vblank IRQ is disabled, send event directly */ 208 spin_lock_irq(&drm->event_lock); 209 drm_crtc_send_vblank_event(&malidp->crtc, malidp->event); 210 malidp->event = NULL; 211 spin_unlock_irq(&drm->event_lock); 212 } 213 drm_atomic_helper_commit_hw_done(state); 214 } 215 216 static void malidp_atomic_commit_tail(struct drm_atomic_state *state) 217 { 218 struct drm_device *drm = state->dev; 219 struct drm_crtc *crtc; 220 struct drm_crtc_state *old_crtc_state; 221 int i; 222 223 pm_runtime_get_sync(drm->dev); 224 225 drm_atomic_helper_commit_modeset_disables(drm, state); 226 227 for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { 228 malidp_atomic_commit_update_gamma(crtc, old_crtc_state); 229 malidp_atomic_commit_update_coloradj(crtc, old_crtc_state); 230 malidp_atomic_commit_se_config(crtc, old_crtc_state); 231 } 232 233 drm_atomic_helper_commit_planes(drm, state, 0); 234 235 drm_atomic_helper_commit_modeset_enables(drm, state); 236 237 malidp_atomic_commit_hw_done(state); 238 239 pm_runtime_put(drm->dev); 240 241 drm_atomic_helper_cleanup_planes(drm, state); 242 } 243 244 static const struct drm_mode_config_helper_funcs malidp_mode_config_helpers = { 245 .atomic_commit_tail = malidp_atomic_commit_tail, 246 }; 247 248 static const struct drm_mode_config_funcs malidp_mode_config_funcs = { 249 .fb_create = drm_gem_fb_create, 250 .output_poll_changed = drm_fb_helper_output_poll_changed, 251 .atomic_check = drm_atomic_helper_check, 252 .atomic_commit = drm_atomic_helper_commit, 253 }; 254 255 static int malidp_init(struct drm_device *drm) 256 { 257 int ret; 258 struct malidp_drm *malidp = drm->dev_private; 259 struct malidp_hw_device *hwdev = malidp->dev; 260 261 drm_mode_config_init(drm); 262 263 drm->mode_config.min_width = hwdev->min_line_size; 264 drm->mode_config.min_height = hwdev->min_line_size; 265 drm->mode_config.max_width = hwdev->max_line_size; 266 drm->mode_config.max_height = hwdev->max_line_size; 267 drm->mode_config.funcs = &malidp_mode_config_funcs; 268 drm->mode_config.helper_private = &malidp_mode_config_helpers; 269 270 ret = malidp_crtc_init(drm); 271 if (ret) { 272 drm_mode_config_cleanup(drm); 273 return ret; 274 } 275 276 return 0; 277 } 278 279 static void malidp_fini(struct drm_device *drm) 280 { 281 drm_atomic_helper_shutdown(drm); 282 drm_mode_config_cleanup(drm); 283 } 284 285 static int malidp_irq_init(struct platform_device *pdev) 286 { 287 int irq_de, irq_se, ret = 0; 288 struct drm_device *drm = dev_get_drvdata(&pdev->dev); 289 290 /* fetch the interrupts from DT */ 291 irq_de = platform_get_irq_byname(pdev, "DE"); 292 if (irq_de < 0) { 293 DRM_ERROR("no 'DE' IRQ specified!\n"); 294 return irq_de; 295 } 296 irq_se = platform_get_irq_byname(pdev, "SE"); 297 if (irq_se < 0) { 298 DRM_ERROR("no 'SE' IRQ specified!\n"); 299 return irq_se; 300 } 301 302 ret = malidp_de_irq_init(drm, irq_de); 303 if (ret) 304 return ret; 305 306 ret = malidp_se_irq_init(drm, irq_se); 307 if (ret) { 308 malidp_de_irq_fini(drm); 309 return ret; 310 } 311 312 return 0; 313 } 314 315 DEFINE_DRM_GEM_CMA_FOPS(fops); 316 317 static int malidp_dumb_create(struct drm_file *file_priv, 318 struct drm_device *drm, 319 struct drm_mode_create_dumb *args) 320 { 321 struct malidp_drm *malidp = drm->dev_private; 322 /* allocate for the worst case scenario, i.e. rotated buffers */ 323 u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1); 324 325 args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), alignment); 326 327 return drm_gem_cma_dumb_create_internal(file_priv, drm, args); 328 } 329 330 static struct drm_driver malidp_driver = { 331 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | 332 DRIVER_PRIME, 333 .lastclose = drm_fb_helper_lastclose, 334 .gem_free_object_unlocked = drm_gem_cma_free_object, 335 .gem_vm_ops = &drm_gem_cma_vm_ops, 336 .dumb_create = malidp_dumb_create, 337 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 338 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 339 .gem_prime_export = drm_gem_prime_export, 340 .gem_prime_import = drm_gem_prime_import, 341 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 342 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 343 .gem_prime_vmap = drm_gem_cma_prime_vmap, 344 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 345 .gem_prime_mmap = drm_gem_cma_prime_mmap, 346 .fops = &fops, 347 .name = "mali-dp", 348 .desc = "ARM Mali Display Processor driver", 349 .date = "20160106", 350 .major = 1, 351 .minor = 0, 352 }; 353 354 static const struct of_device_id malidp_drm_of_match[] = { 355 { 356 .compatible = "arm,mali-dp500", 357 .data = &malidp_device[MALIDP_500] 358 }, 359 { 360 .compatible = "arm,mali-dp550", 361 .data = &malidp_device[MALIDP_550] 362 }, 363 { 364 .compatible = "arm,mali-dp650", 365 .data = &malidp_device[MALIDP_650] 366 }, 367 {}, 368 }; 369 MODULE_DEVICE_TABLE(of, malidp_drm_of_match); 370 371 static bool malidp_is_compatible_hw_id(struct malidp_hw_device *hwdev, 372 const struct of_device_id *dev_id) 373 { 374 u32 core_id; 375 const char *compatstr_dp500 = "arm,mali-dp500"; 376 bool is_dp500; 377 bool dt_is_dp500; 378 379 /* 380 * The DP500 CORE_ID register is in a different location, so check it 381 * first. If the product id field matches, then this is DP500, otherwise 382 * check the DP550/650 CORE_ID register. 383 */ 384 core_id = malidp_hw_read(hwdev, MALIDP500_DC_BASE + MALIDP_DE_CORE_ID); 385 /* Offset 0x18 will never read 0x500 on products other than DP500. */ 386 is_dp500 = (MALIDP_PRODUCT_ID(core_id) == 0x500); 387 dt_is_dp500 = strnstr(dev_id->compatible, compatstr_dp500, 388 sizeof(dev_id->compatible)) != NULL; 389 if (is_dp500 != dt_is_dp500) { 390 DRM_ERROR("Device-tree expects %s, but hardware %s DP500.\n", 391 dev_id->compatible, is_dp500 ? "is" : "is not"); 392 return false; 393 } else if (!dt_is_dp500) { 394 u16 product_id; 395 char buf[32]; 396 397 core_id = malidp_hw_read(hwdev, 398 MALIDP550_DC_BASE + MALIDP_DE_CORE_ID); 399 product_id = MALIDP_PRODUCT_ID(core_id); 400 snprintf(buf, sizeof(buf), "arm,mali-dp%X", product_id); 401 if (!strnstr(dev_id->compatible, buf, 402 sizeof(dev_id->compatible))) { 403 DRM_ERROR("Device-tree expects %s, but hardware is DP%03X.\n", 404 dev_id->compatible, product_id); 405 return false; 406 } 407 } 408 return true; 409 } 410 411 static bool malidp_has_sufficient_address_space(const struct resource *res, 412 const struct of_device_id *dev_id) 413 { 414 resource_size_t res_size = resource_size(res); 415 const char *compatstr_dp500 = "arm,mali-dp500"; 416 417 if (!strnstr(dev_id->compatible, compatstr_dp500, 418 sizeof(dev_id->compatible))) 419 return res_size >= MALIDP550_ADDR_SPACE_SIZE; 420 else if (res_size < MALIDP500_ADDR_SPACE_SIZE) 421 return false; 422 return true; 423 } 424 425 static ssize_t core_id_show(struct device *dev, struct device_attribute *attr, 426 char *buf) 427 { 428 struct drm_device *drm = dev_get_drvdata(dev); 429 struct malidp_drm *malidp = drm->dev_private; 430 431 return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id); 432 } 433 434 DEVICE_ATTR_RO(core_id); 435 436 static int malidp_init_sysfs(struct device *dev) 437 { 438 int ret = device_create_file(dev, &dev_attr_core_id); 439 440 if (ret) 441 DRM_ERROR("failed to create device file for core_id\n"); 442 443 return ret; 444 } 445 446 static void malidp_fini_sysfs(struct device *dev) 447 { 448 device_remove_file(dev, &dev_attr_core_id); 449 } 450 451 #define MAX_OUTPUT_CHANNELS 3 452 453 static int malidp_runtime_pm_suspend(struct device *dev) 454 { 455 struct drm_device *drm = dev_get_drvdata(dev); 456 struct malidp_drm *malidp = drm->dev_private; 457 struct malidp_hw_device *hwdev = malidp->dev; 458 459 /* we can only suspend if the hardware is in config mode */ 460 WARN_ON(!hwdev->hw->in_config_mode(hwdev)); 461 462 hwdev->pm_suspended = true; 463 clk_disable_unprepare(hwdev->mclk); 464 clk_disable_unprepare(hwdev->aclk); 465 clk_disable_unprepare(hwdev->pclk); 466 467 return 0; 468 } 469 470 static int malidp_runtime_pm_resume(struct device *dev) 471 { 472 struct drm_device *drm = dev_get_drvdata(dev); 473 struct malidp_drm *malidp = drm->dev_private; 474 struct malidp_hw_device *hwdev = malidp->dev; 475 476 clk_prepare_enable(hwdev->pclk); 477 clk_prepare_enable(hwdev->aclk); 478 clk_prepare_enable(hwdev->mclk); 479 hwdev->pm_suspended = false; 480 481 return 0; 482 } 483 484 static int malidp_bind(struct device *dev) 485 { 486 struct resource *res; 487 struct drm_device *drm; 488 struct malidp_drm *malidp; 489 struct malidp_hw_device *hwdev; 490 struct platform_device *pdev = to_platform_device(dev); 491 struct of_device_id const *dev_id; 492 /* number of lines for the R, G and B output */ 493 u8 output_width[MAX_OUTPUT_CHANNELS]; 494 int ret = 0, i; 495 u32 version, out_depth = 0; 496 497 malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL); 498 if (!malidp) 499 return -ENOMEM; 500 501 hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL); 502 if (!hwdev) 503 return -ENOMEM; 504 505 hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev); 506 malidp->dev = hwdev; 507 508 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 509 hwdev->regs = devm_ioremap_resource(dev, res); 510 if (IS_ERR(hwdev->regs)) 511 return PTR_ERR(hwdev->regs); 512 513 hwdev->pclk = devm_clk_get(dev, "pclk"); 514 if (IS_ERR(hwdev->pclk)) 515 return PTR_ERR(hwdev->pclk); 516 517 hwdev->aclk = devm_clk_get(dev, "aclk"); 518 if (IS_ERR(hwdev->aclk)) 519 return PTR_ERR(hwdev->aclk); 520 521 hwdev->mclk = devm_clk_get(dev, "mclk"); 522 if (IS_ERR(hwdev->mclk)) 523 return PTR_ERR(hwdev->mclk); 524 525 hwdev->pxlclk = devm_clk_get(dev, "pxlclk"); 526 if (IS_ERR(hwdev->pxlclk)) 527 return PTR_ERR(hwdev->pxlclk); 528 529 /* Get the optional framebuffer memory resource */ 530 ret = of_reserved_mem_device_init(dev); 531 if (ret && ret != -ENODEV) 532 return ret; 533 534 drm = drm_dev_alloc(&malidp_driver, dev); 535 if (IS_ERR(drm)) { 536 ret = PTR_ERR(drm); 537 goto alloc_fail; 538 } 539 540 drm->dev_private = malidp; 541 dev_set_drvdata(dev, drm); 542 543 /* Enable power management */ 544 pm_runtime_enable(dev); 545 546 /* Resume device to enable the clocks */ 547 if (pm_runtime_enabled(dev)) 548 pm_runtime_get_sync(dev); 549 else 550 malidp_runtime_pm_resume(dev); 551 552 dev_id = of_match_device(malidp_drm_of_match, dev); 553 if (!dev_id) { 554 ret = -EINVAL; 555 goto query_hw_fail; 556 } 557 558 if (!malidp_has_sufficient_address_space(res, dev_id)) { 559 DRM_ERROR("Insufficient address space in device-tree.\n"); 560 ret = -EINVAL; 561 goto query_hw_fail; 562 } 563 564 if (!malidp_is_compatible_hw_id(hwdev, dev_id)) { 565 ret = -EINVAL; 566 goto query_hw_fail; 567 } 568 569 ret = hwdev->hw->query_hw(hwdev); 570 if (ret) { 571 DRM_ERROR("Invalid HW configuration\n"); 572 goto query_hw_fail; 573 } 574 575 version = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_DE_CORE_ID); 576 DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16, 577 (version >> 12) & 0xf, (version >> 8) & 0xf); 578 579 malidp->core_id = version; 580 581 /* set the number of lines used for output of RGB data */ 582 ret = of_property_read_u8_array(dev->of_node, 583 "arm,malidp-output-port-lines", 584 output_width, MAX_OUTPUT_CHANNELS); 585 if (ret) 586 goto query_hw_fail; 587 588 for (i = 0; i < MAX_OUTPUT_CHANNELS; i++) 589 out_depth = (out_depth << 8) | (output_width[i] & 0xf); 590 malidp_hw_write(hwdev, out_depth, hwdev->hw->map.out_depth_base); 591 592 atomic_set(&malidp->config_valid, 0); 593 init_waitqueue_head(&malidp->wq); 594 595 ret = malidp_init(drm); 596 if (ret < 0) 597 goto query_hw_fail; 598 599 ret = malidp_init_sysfs(dev); 600 if (ret) 601 goto init_fail; 602 603 /* Set the CRTC's port so that the encoder component can find it */ 604 malidp->crtc.port = of_graph_get_port_by_id(dev->of_node, 0); 605 606 ret = component_bind_all(dev, drm); 607 if (ret) { 608 DRM_ERROR("Failed to bind all components\n"); 609 goto bind_fail; 610 } 611 612 ret = malidp_irq_init(pdev); 613 if (ret < 0) 614 goto irq_init_fail; 615 616 drm->irq_enabled = true; 617 618 ret = drm_vblank_init(drm, drm->mode_config.num_crtc); 619 if (ret < 0) { 620 DRM_ERROR("failed to initialise vblank\n"); 621 goto vblank_fail; 622 } 623 pm_runtime_put(dev); 624 625 drm_mode_config_reset(drm); 626 627 ret = drm_fb_cma_fbdev_init(drm, 32, 0); 628 if (ret) 629 goto fbdev_fail; 630 631 drm_kms_helper_poll_init(drm); 632 633 ret = drm_dev_register(drm, 0); 634 if (ret) 635 goto register_fail; 636 637 return 0; 638 639 register_fail: 640 drm_fb_cma_fbdev_fini(drm); 641 drm_kms_helper_poll_fini(drm); 642 fbdev_fail: 643 pm_runtime_get_sync(dev); 644 vblank_fail: 645 malidp_se_irq_fini(drm); 646 malidp_de_irq_fini(drm); 647 drm->irq_enabled = false; 648 irq_init_fail: 649 component_unbind_all(dev, drm); 650 bind_fail: 651 of_node_put(malidp->crtc.port); 652 malidp->crtc.port = NULL; 653 init_fail: 654 malidp_fini_sysfs(dev); 655 malidp_fini(drm); 656 query_hw_fail: 657 pm_runtime_put(dev); 658 if (pm_runtime_enabled(dev)) 659 pm_runtime_disable(dev); 660 else 661 malidp_runtime_pm_suspend(dev); 662 drm->dev_private = NULL; 663 dev_set_drvdata(dev, NULL); 664 drm_dev_put(drm); 665 alloc_fail: 666 of_reserved_mem_device_release(dev); 667 668 return ret; 669 } 670 671 static void malidp_unbind(struct device *dev) 672 { 673 struct drm_device *drm = dev_get_drvdata(dev); 674 struct malidp_drm *malidp = drm->dev_private; 675 676 drm_dev_unregister(drm); 677 drm_fb_cma_fbdev_fini(drm); 678 drm_kms_helper_poll_fini(drm); 679 pm_runtime_get_sync(dev); 680 drm_crtc_vblank_off(&malidp->crtc); 681 malidp_se_irq_fini(drm); 682 malidp_de_irq_fini(drm); 683 drm->irq_enabled = false; 684 component_unbind_all(dev, drm); 685 of_node_put(malidp->crtc.port); 686 malidp->crtc.port = NULL; 687 malidp_fini_sysfs(dev); 688 malidp_fini(drm); 689 pm_runtime_put(dev); 690 if (pm_runtime_enabled(dev)) 691 pm_runtime_disable(dev); 692 else 693 malidp_runtime_pm_suspend(dev); 694 drm->dev_private = NULL; 695 dev_set_drvdata(dev, NULL); 696 drm_dev_put(drm); 697 of_reserved_mem_device_release(dev); 698 } 699 700 static const struct component_master_ops malidp_master_ops = { 701 .bind = malidp_bind, 702 .unbind = malidp_unbind, 703 }; 704 705 static int malidp_compare_dev(struct device *dev, void *data) 706 { 707 struct device_node *np = data; 708 709 return dev->of_node == np; 710 } 711 712 static int malidp_platform_probe(struct platform_device *pdev) 713 { 714 struct device_node *port; 715 struct component_match *match = NULL; 716 717 if (!pdev->dev.of_node) 718 return -ENODEV; 719 720 /* there is only one output port inside each device, find it */ 721 port = of_graph_get_remote_node(pdev->dev.of_node, 0, 0); 722 if (!port) 723 return -ENODEV; 724 725 drm_of_component_match_add(&pdev->dev, &match, malidp_compare_dev, 726 port); 727 of_node_put(port); 728 return component_master_add_with_match(&pdev->dev, &malidp_master_ops, 729 match); 730 } 731 732 static int malidp_platform_remove(struct platform_device *pdev) 733 { 734 component_master_del(&pdev->dev, &malidp_master_ops); 735 return 0; 736 } 737 738 static int __maybe_unused malidp_pm_suspend(struct device *dev) 739 { 740 struct drm_device *drm = dev_get_drvdata(dev); 741 742 return drm_mode_config_helper_suspend(drm); 743 } 744 745 static int __maybe_unused malidp_pm_resume(struct device *dev) 746 { 747 struct drm_device *drm = dev_get_drvdata(dev); 748 749 drm_mode_config_helper_resume(drm); 750 751 return 0; 752 } 753 754 static const struct dev_pm_ops malidp_pm_ops = { 755 SET_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend, malidp_pm_resume) \ 756 SET_RUNTIME_PM_OPS(malidp_runtime_pm_suspend, malidp_runtime_pm_resume, NULL) 757 }; 758 759 static struct platform_driver malidp_platform_driver = { 760 .probe = malidp_platform_probe, 761 .remove = malidp_platform_remove, 762 .driver = { 763 .name = "mali-dp", 764 .pm = &malidp_pm_ops, 765 .of_match_table = malidp_drm_of_match, 766 }, 767 }; 768 769 module_platform_driver(malidp_platform_driver); 770 771 MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>"); 772 MODULE_DESCRIPTION("ARM Mali DP DRM driver"); 773 MODULE_LICENSE("GPL v2"); 774