.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* exynos_drm_vidi.c |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2012 Samsung Electronics Co.Ltd |
---|
4 | 5 | * Authors: |
---|
5 | 6 | * Inki Dae <inki.dae@samsung.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify it |
---|
8 | | - * under the terms of the GNU General Public License as published by the |
---|
9 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
10 | | - * option) any later version. |
---|
11 | | - * |
---|
12 | 7 | */ |
---|
13 | | -#include <drm/drmP.h> |
---|
14 | 8 | |
---|
| 9 | +#include <linux/component.h> |
---|
15 | 10 | #include <linux/kernel.h> |
---|
16 | 11 | #include <linux/platform_device.h> |
---|
17 | | -#include <linux/component.h> |
---|
18 | 12 | #include <linux/timer.h> |
---|
19 | 13 | |
---|
| 14 | +#include <drm/drm_atomic_helper.h> |
---|
| 15 | +#include <drm/drm_edid.h> |
---|
| 16 | +#include <drm/drm_probe_helper.h> |
---|
| 17 | +#include <drm/drm_simple_kms_helper.h> |
---|
| 18 | +#include <drm/drm_vblank.h> |
---|
20 | 19 | #include <drm/exynos_drm.h> |
---|
21 | 20 | |
---|
22 | | -#include <drm/drm_edid.h> |
---|
23 | | -#include <drm/drm_crtc_helper.h> |
---|
24 | | -#include <drm/drm_atomic_helper.h> |
---|
25 | | - |
---|
26 | | -#include "exynos_drm_drv.h" |
---|
27 | 21 | #include "exynos_drm_crtc.h" |
---|
| 22 | +#include "exynos_drm_drv.h" |
---|
28 | 23 | #include "exynos_drm_fb.h" |
---|
29 | 24 | #include "exynos_drm_plane.h" |
---|
30 | 25 | #include "exynos_drm_vidi.h" |
---|
.. | .. |
---|
40 | 35 | |
---|
41 | 36 | struct vidi_context { |
---|
42 | 37 | struct drm_encoder encoder; |
---|
43 | | - struct platform_device *pdev; |
---|
44 | 38 | struct drm_device *drm_dev; |
---|
| 39 | + struct device *dev; |
---|
45 | 40 | struct exynos_drm_crtc *crtc; |
---|
46 | 41 | struct drm_connector connector; |
---|
47 | 42 | struct exynos_drm_plane planes[WINDOWS_NR]; |
---|
.. | .. |
---|
123 | 118 | return; |
---|
124 | 119 | |
---|
125 | 120 | addr = exynos_drm_fb_dma_addr(state->fb, 0); |
---|
126 | | - DRM_DEBUG_KMS("dma_addr = %pad\n", &addr); |
---|
| 121 | + DRM_DEV_DEBUG_KMS(ctx->dev, "dma_addr = %pad\n", &addr); |
---|
127 | 122 | } |
---|
128 | 123 | |
---|
129 | | -static void vidi_enable(struct exynos_drm_crtc *crtc) |
---|
| 124 | +static void vidi_atomic_enable(struct exynos_drm_crtc *crtc) |
---|
130 | 125 | { |
---|
131 | 126 | struct vidi_context *ctx = crtc->ctx; |
---|
132 | 127 | |
---|
.. | .. |
---|
139 | 134 | drm_crtc_vblank_on(&crtc->base); |
---|
140 | 135 | } |
---|
141 | 136 | |
---|
142 | | -static void vidi_disable(struct exynos_drm_crtc *crtc) |
---|
| 137 | +static void vidi_atomic_disable(struct exynos_drm_crtc *crtc) |
---|
143 | 138 | { |
---|
144 | 139 | struct vidi_context *ctx = crtc->ctx; |
---|
145 | 140 | |
---|
.. | .. |
---|
153 | 148 | } |
---|
154 | 149 | |
---|
155 | 150 | static const struct exynos_drm_crtc_ops vidi_crtc_ops = { |
---|
156 | | - .enable = vidi_enable, |
---|
157 | | - .disable = vidi_disable, |
---|
| 151 | + .atomic_enable = vidi_atomic_enable, |
---|
| 152 | + .atomic_disable = vidi_atomic_disable, |
---|
158 | 153 | .enable_vblank = vidi_enable_vblank, |
---|
159 | 154 | .disable_vblank = vidi_disable_vblank, |
---|
160 | 155 | .update_plane = vidi_update_plane, |
---|
.. | .. |
---|
205 | 200 | |
---|
206 | 201 | /* if raw_edid isn't same as fake data then it can't be tested. */ |
---|
207 | 202 | if (ctx->raw_edid != (struct edid *)fake_edid_info) { |
---|
208 | | - DRM_DEBUG_KMS("edid data is not fake data.\n"); |
---|
| 203 | + DRM_DEV_DEBUG_KMS(dev, "edid data is not fake data.\n"); |
---|
209 | 204 | return -EINVAL; |
---|
210 | 205 | } |
---|
211 | 206 | |
---|
212 | | - DRM_DEBUG_KMS("requested connection.\n"); |
---|
| 207 | + DRM_DEV_DEBUG_KMS(dev, "requested connection.\n"); |
---|
213 | 208 | |
---|
214 | 209 | drm_helper_hpd_irq_event(ctx->drm_dev); |
---|
215 | 210 | |
---|
.. | .. |
---|
219 | 214 | static DEVICE_ATTR(connection, 0644, vidi_show_connection, |
---|
220 | 215 | vidi_store_connection); |
---|
221 | 216 | |
---|
| 217 | +static struct attribute *vidi_attrs[] = { |
---|
| 218 | + &dev_attr_connection.attr, |
---|
| 219 | + NULL, |
---|
| 220 | +}; |
---|
| 221 | +ATTRIBUTE_GROUPS(vidi); |
---|
| 222 | + |
---|
222 | 223 | int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, |
---|
223 | 224 | struct drm_file *file_priv) |
---|
224 | 225 | { |
---|
.. | .. |
---|
226 | 227 | struct drm_exynos_vidi_connection *vidi = data; |
---|
227 | 228 | |
---|
228 | 229 | if (!vidi) { |
---|
229 | | - DRM_DEBUG_KMS("user data for vidi is null.\n"); |
---|
| 230 | + DRM_DEV_DEBUG_KMS(ctx->dev, |
---|
| 231 | + "user data for vidi is null.\n"); |
---|
230 | 232 | return -EINVAL; |
---|
231 | 233 | } |
---|
232 | 234 | |
---|
233 | 235 | if (vidi->connection > 1) { |
---|
234 | | - DRM_DEBUG_KMS("connection should be 0 or 1.\n"); |
---|
| 236 | + DRM_DEV_DEBUG_KMS(ctx->dev, |
---|
| 237 | + "connection should be 0 or 1.\n"); |
---|
235 | 238 | return -EINVAL; |
---|
236 | 239 | } |
---|
237 | 240 | |
---|
238 | 241 | if (ctx->connected == vidi->connection) { |
---|
239 | | - DRM_DEBUG_KMS("same connection request.\n"); |
---|
| 242 | + DRM_DEV_DEBUG_KMS(ctx->dev, |
---|
| 243 | + "same connection request.\n"); |
---|
240 | 244 | return -EINVAL; |
---|
241 | 245 | } |
---|
242 | 246 | |
---|
.. | .. |
---|
245 | 249 | |
---|
246 | 250 | raw_edid = (struct edid *)(unsigned long)vidi->edid; |
---|
247 | 251 | if (!drm_edid_is_valid(raw_edid)) { |
---|
248 | | - DRM_DEBUG_KMS("edid data is invalid.\n"); |
---|
| 252 | + DRM_DEV_DEBUG_KMS(ctx->dev, |
---|
| 253 | + "edid data is invalid.\n"); |
---|
249 | 254 | return -EINVAL; |
---|
250 | 255 | } |
---|
251 | 256 | ctx->raw_edid = drm_edid_duplicate(raw_edid); |
---|
252 | 257 | if (!ctx->raw_edid) { |
---|
253 | | - DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); |
---|
| 258 | + DRM_DEV_DEBUG_KMS(ctx->dev, |
---|
| 259 | + "failed to allocate raw_edid.\n"); |
---|
254 | 260 | return -ENOMEM; |
---|
255 | 261 | } |
---|
256 | 262 | } else { |
---|
.. | .. |
---|
308 | 314 | * to ctx->raw_edid through specific ioctl. |
---|
309 | 315 | */ |
---|
310 | 316 | if (!ctx->raw_edid) { |
---|
311 | | - DRM_DEBUG_KMS("raw_edid is null.\n"); |
---|
| 317 | + DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); |
---|
312 | 318 | return -EFAULT; |
---|
313 | 319 | } |
---|
314 | 320 | |
---|
315 | 321 | edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; |
---|
316 | 322 | edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); |
---|
317 | 323 | if (!edid) { |
---|
318 | | - DRM_DEBUG_KMS("failed to allocate edid\n"); |
---|
| 324 | + DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); |
---|
319 | 325 | return -ENOMEM; |
---|
320 | 326 | } |
---|
321 | 327 | |
---|
.. | .. |
---|
339 | 345 | ret = drm_connector_init(ctx->drm_dev, connector, |
---|
340 | 346 | &vidi_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); |
---|
341 | 347 | if (ret) { |
---|
342 | | - DRM_ERROR("Failed to initialize connector with drm\n"); |
---|
| 348 | + DRM_DEV_ERROR(ctx->dev, |
---|
| 349 | + "Failed to initialize connector with drm\n"); |
---|
343 | 350 | return ret; |
---|
344 | 351 | } |
---|
345 | 352 | |
---|
.. | .. |
---|
367 | 374 | .mode_set = exynos_vidi_mode_set, |
---|
368 | 375 | .enable = exynos_vidi_enable, |
---|
369 | 376 | .disable = exynos_vidi_disable, |
---|
370 | | -}; |
---|
371 | | - |
---|
372 | | -static const struct drm_encoder_funcs exynos_vidi_encoder_funcs = { |
---|
373 | | - .destroy = drm_encoder_cleanup, |
---|
374 | 377 | }; |
---|
375 | 378 | |
---|
376 | 379 | static int vidi_bind(struct device *dev, struct device *master, void *data) |
---|
.. | .. |
---|
402 | 405 | ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, |
---|
403 | 406 | EXYNOS_DISPLAY_TYPE_VIDI, &vidi_crtc_ops, ctx); |
---|
404 | 407 | if (IS_ERR(ctx->crtc)) { |
---|
405 | | - DRM_ERROR("failed to create crtc.\n"); |
---|
| 408 | + DRM_DEV_ERROR(dev, "failed to create crtc.\n"); |
---|
406 | 409 | return PTR_ERR(ctx->crtc); |
---|
407 | 410 | } |
---|
408 | 411 | |
---|
409 | | - drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs, |
---|
410 | | - DRM_MODE_ENCODER_TMDS, NULL); |
---|
| 412 | + drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS); |
---|
411 | 413 | |
---|
412 | 414 | drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs); |
---|
413 | 415 | |
---|
.. | .. |
---|
417 | 419 | |
---|
418 | 420 | ret = vidi_create_connector(encoder); |
---|
419 | 421 | if (ret) { |
---|
420 | | - DRM_ERROR("failed to create connector ret = %d\n", ret); |
---|
| 422 | + DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n", |
---|
| 423 | + ret); |
---|
421 | 424 | drm_encoder_cleanup(encoder); |
---|
422 | 425 | return ret; |
---|
423 | 426 | } |
---|
.. | .. |
---|
441 | 444 | static int vidi_probe(struct platform_device *pdev) |
---|
442 | 445 | { |
---|
443 | 446 | struct vidi_context *ctx; |
---|
444 | | - int ret; |
---|
| 447 | + struct device *dev = &pdev->dev; |
---|
445 | 448 | |
---|
446 | | - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
---|
| 449 | + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); |
---|
447 | 450 | if (!ctx) |
---|
448 | 451 | return -ENOMEM; |
---|
449 | 452 | |
---|
450 | | - ctx->pdev = pdev; |
---|
| 453 | + ctx->dev = dev; |
---|
451 | 454 | |
---|
452 | 455 | timer_setup(&ctx->timer, vidi_fake_vblank_timer, 0); |
---|
453 | 456 | |
---|
.. | .. |
---|
455 | 458 | |
---|
456 | 459 | platform_set_drvdata(pdev, ctx); |
---|
457 | 460 | |
---|
458 | | - ret = device_create_file(&pdev->dev, &dev_attr_connection); |
---|
459 | | - if (ret < 0) { |
---|
460 | | - DRM_ERROR("failed to create connection sysfs.\n"); |
---|
461 | | - return ret; |
---|
462 | | - } |
---|
463 | | - |
---|
464 | | - ret = component_add(&pdev->dev, &vidi_component_ops); |
---|
465 | | - if (ret) |
---|
466 | | - goto err_remove_file; |
---|
467 | | - |
---|
468 | | - return ret; |
---|
469 | | - |
---|
470 | | -err_remove_file: |
---|
471 | | - device_remove_file(&pdev->dev, &dev_attr_connection); |
---|
472 | | - |
---|
473 | | - return ret; |
---|
| 461 | + return component_add(dev, &vidi_component_ops); |
---|
474 | 462 | } |
---|
475 | 463 | |
---|
476 | 464 | static int vidi_remove(struct platform_device *pdev) |
---|
.. | .. |
---|
495 | 483 | .driver = { |
---|
496 | 484 | .name = "exynos-drm-vidi", |
---|
497 | 485 | .owner = THIS_MODULE, |
---|
| 486 | + .dev_groups = vidi_groups, |
---|
498 | 487 | }, |
---|
499 | 488 | }; |
---|