1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012 Avionic Design GmbH
4 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
8 #include <linux/debugfs.h>
9 #include <linux/delay.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/iommu.h>
12 #include <linux/interconnect.h>
13 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_domain.h>
17 #include <linux/pm_opp.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/reset.h>
21 #include <soc/tegra/common.h>
22 #include <soc/tegra/pmc.h>
24 #include <drm/drm_atomic.h>
25 #include <drm/drm_atomic_helper.h>
26 #include <drm/drm_blend.h>
27 #include <drm/drm_debugfs.h>
28 #include <drm/drm_fourcc.h>
29 #include <drm/drm_framebuffer.h>
30 #include <drm/drm_vblank.h>
38 static void tegra_crtc_atomic_destroy_state(struct drm_crtc
*crtc
,
39 struct drm_crtc_state
*state
);
41 static void tegra_dc_stats_reset(struct tegra_dc_stats
*stats
)
49 /* Reads the active copy of a register. */
50 static u32
tegra_dc_readl_active(struct tegra_dc
*dc
, unsigned long offset
)
54 tegra_dc_writel(dc
, READ_MUX
, DC_CMD_STATE_ACCESS
);
55 value
= tegra_dc_readl(dc
, offset
);
56 tegra_dc_writel(dc
, 0, DC_CMD_STATE_ACCESS
);
61 static inline unsigned int tegra_plane_offset(struct tegra_plane
*plane
,
64 if (offset
>= 0x500 && offset
<= 0x638) {
65 offset
= 0x000 + (offset
- 0x500);
66 return plane
->offset
+ offset
;
69 if (offset
>= 0x700 && offset
<= 0x719) {
70 offset
= 0x180 + (offset
- 0x700);
71 return plane
->offset
+ offset
;
74 if (offset
>= 0x800 && offset
<= 0x839) {
75 offset
= 0x1c0 + (offset
- 0x800);
76 return plane
->offset
+ offset
;
79 dev_WARN(plane
->dc
->dev
, "invalid offset: %x\n", offset
);
81 return plane
->offset
+ offset
;
84 static inline u32
tegra_plane_readl(struct tegra_plane
*plane
,
87 return tegra_dc_readl(plane
->dc
, tegra_plane_offset(plane
, offset
));
90 static inline void tegra_plane_writel(struct tegra_plane
*plane
, u32 value
,
93 tegra_dc_writel(plane
->dc
, value
, tegra_plane_offset(plane
, offset
));
96 bool tegra_dc_has_output(struct tegra_dc
*dc
, struct device
*dev
)
98 struct device_node
*np
= dc
->dev
->of_node
;
99 struct of_phandle_iterator it
;
102 of_for_each_phandle(&it
, err
, np
, "nvidia,outputs", NULL
, 0)
103 if (it
.node
== dev
->of_node
)
110 * Double-buffered registers have two copies: ASSEMBLY and ACTIVE. When the
111 * *_ACT_REQ bits are set the ASSEMBLY copy is latched into the ACTIVE copy.
112 * Latching happens mmediately if the display controller is in STOP mode or
113 * on the next frame boundary otherwise.
115 * Triple-buffered registers have three copies: ASSEMBLY, ARM and ACTIVE. The
116 * ASSEMBLY copy is latched into the ARM copy immediately after *_UPDATE bits
117 * are written. When the *_ACT_REQ bits are written, the ARM copy is latched
118 * into the ACTIVE copy, either immediately if the display controller is in
119 * STOP mode, or at the next frame boundary otherwise.
121 void tegra_dc_commit(struct tegra_dc
*dc
)
123 tegra_dc_writel(dc
, GENERAL_ACT_REQ
<< 8, DC_CMD_STATE_CONTROL
);
124 tegra_dc_writel(dc
, GENERAL_ACT_REQ
, DC_CMD_STATE_CONTROL
);
127 static inline u32
compute_dda_inc(unsigned int in
, unsigned int out
, bool v
,
130 fixed20_12 outf
= dfixed_init(out
);
131 fixed20_12 inf
= dfixed_init(in
);
152 outf
.full
= max_t(u32
, outf
.full
- dfixed_const(1), dfixed_const(1));
153 inf
.full
-= dfixed_const(1);
155 dda_inc
= dfixed_div(inf
, outf
);
156 dda_inc
= min_t(u32
, dda_inc
, dfixed_const(max
));
161 static inline u32
compute_initial_dda(unsigned int in
)
163 fixed20_12 inf
= dfixed_init(in
);
164 return dfixed_frac(inf
);
167 static void tegra_plane_setup_blending_legacy(struct tegra_plane
*plane
)
169 u32 background
[3] = {
170 BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE
,
171 BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE
,
172 BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE
,
174 u32 foreground
= BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255) |
175 BLEND_COLOR_KEY_NONE
;
176 u32 blendnokey
= BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255);
177 struct tegra_plane_state
*state
;
181 /* disable blending for non-overlapping case */
182 tegra_plane_writel(plane
, blendnokey
, DC_WIN_BLEND_NOKEY
);
183 tegra_plane_writel(plane
, foreground
, DC_WIN_BLEND_1WIN
);
185 state
= to_tegra_plane_state(plane
->base
.state
);
189 * Since custom fix-weight blending isn't utilized and weight
190 * of top window is set to max, we can enforce dependent
191 * blending which in this case results in transparent bottom
192 * window if top window is opaque and if top window enables
193 * alpha blending, then bottom window is getting alpha value
194 * of 1 minus the sum of alpha components of the overlapping
197 background
[0] |= BLEND_CONTROL_DEPENDENT
;
198 background
[1] |= BLEND_CONTROL_DEPENDENT
;
201 * The region where three windows overlap is the intersection
202 * of the two regions where two windows overlap. It contributes
203 * to the area if all of the windows on top of it have an alpha
206 switch (state
->base
.normalized_zpos
) {
208 if (state
->blending
[0].alpha
&&
209 state
->blending
[1].alpha
)
210 background
[2] |= BLEND_CONTROL_DEPENDENT
;
214 background
[2] |= BLEND_CONTROL_DEPENDENT
;
219 * Enable alpha blending if pixel format has an alpha
222 foreground
|= BLEND_CONTROL_ALPHA
;
225 * If any of the windows on top of this window is opaque, it
226 * will completely conceal this window within that area. If
227 * top window has an alpha component, it is blended over the
230 for (i
= 0; i
< 2; i
++) {
231 if (state
->blending
[i
].alpha
&&
232 state
->blending
[i
].top
)
233 background
[i
] |= BLEND_CONTROL_DEPENDENT
;
236 switch (state
->base
.normalized_zpos
) {
238 if (state
->blending
[0].alpha
&&
239 state
->blending
[1].alpha
)
240 background
[2] |= BLEND_CONTROL_DEPENDENT
;
245 * When both middle and topmost windows have an alpha,
246 * these windows a mixed together and then the result
247 * is blended over the bottom window.
249 if (state
->blending
[0].alpha
&&
250 state
->blending
[0].top
)
251 background
[2] |= BLEND_CONTROL_ALPHA
;
253 if (state
->blending
[1].alpha
&&
254 state
->blending
[1].top
)
255 background
[2] |= BLEND_CONTROL_ALPHA
;
260 switch (state
->base
.normalized_zpos
) {
262 tegra_plane_writel(plane
, background
[0], DC_WIN_BLEND_2WIN_X
);
263 tegra_plane_writel(plane
, background
[1], DC_WIN_BLEND_2WIN_Y
);
264 tegra_plane_writel(plane
, background
[2], DC_WIN_BLEND_3WIN_XY
);
269 * If window B / C is topmost, then X / Y registers are
270 * matching the order of blending[...] state indices,
271 * otherwise a swap is required.
273 if (!state
->blending
[0].top
&& state
->blending
[1].top
) {
274 blending
[0] = foreground
;
275 blending
[1] = background
[1];
277 blending
[0] = background
[0];
278 blending
[1] = foreground
;
281 tegra_plane_writel(plane
, blending
[0], DC_WIN_BLEND_2WIN_X
);
282 tegra_plane_writel(plane
, blending
[1], DC_WIN_BLEND_2WIN_Y
);
283 tegra_plane_writel(plane
, background
[2], DC_WIN_BLEND_3WIN_XY
);
287 tegra_plane_writel(plane
, foreground
, DC_WIN_BLEND_2WIN_X
);
288 tegra_plane_writel(plane
, foreground
, DC_WIN_BLEND_2WIN_Y
);
289 tegra_plane_writel(plane
, foreground
, DC_WIN_BLEND_3WIN_XY
);
294 static void tegra_plane_setup_blending(struct tegra_plane
*plane
,
295 const struct tegra_dc_window
*window
)
299 value
= BLEND_FACTOR_DST_ALPHA_ZERO
| BLEND_FACTOR_SRC_ALPHA_K2
|
300 BLEND_FACTOR_DST_COLOR_NEG_K1_TIMES_SRC
|
301 BLEND_FACTOR_SRC_COLOR_K1_TIMES_SRC
;
302 tegra_plane_writel(plane
, value
, DC_WIN_BLEND_MATCH_SELECT
);
304 value
= BLEND_FACTOR_DST_ALPHA_ZERO
| BLEND_FACTOR_SRC_ALPHA_K2
|
305 BLEND_FACTOR_DST_COLOR_NEG_K1_TIMES_SRC
|
306 BLEND_FACTOR_SRC_COLOR_K1_TIMES_SRC
;
307 tegra_plane_writel(plane
, value
, DC_WIN_BLEND_NOMATCH_SELECT
);
309 value
= K2(255) | K1(255) | WINDOW_LAYER_DEPTH(255 - window
->zpos
);
310 tegra_plane_writel(plane
, value
, DC_WIN_BLEND_LAYER_CONTROL
);
314 tegra_plane_use_horizontal_filtering(struct tegra_plane
*plane
,
315 const struct tegra_dc_window
*window
)
317 struct tegra_dc
*dc
= plane
->dc
;
319 if (window
->src
.w
== window
->dst
.w
)
322 if (plane
->index
== 0 && dc
->soc
->has_win_a_without_filters
)
329 tegra_plane_use_vertical_filtering(struct tegra_plane
*plane
,
330 const struct tegra_dc_window
*window
)
332 struct tegra_dc
*dc
= plane
->dc
;
334 if (window
->src
.h
== window
->dst
.h
)
337 if (plane
->index
== 0 && dc
->soc
->has_win_a_without_filters
)
340 if (plane
->index
== 2 && dc
->soc
->has_win_c_without_vert_filter
)
346 static void tegra_dc_setup_window(struct tegra_plane
*plane
,
347 const struct tegra_dc_window
*window
)
349 unsigned h_offset
, v_offset
, h_size
, v_size
, h_dda
, v_dda
, bpp
;
350 struct tegra_dc
*dc
= plane
->dc
;
356 * For YUV planar modes, the number of bytes per pixel takes into
357 * account only the luma component and therefore is 1.
359 yuv
= tegra_plane_format_is_yuv(window
->format
, &planes
, NULL
);
361 bpp
= window
->bits_per_pixel
/ 8;
363 bpp
= (planes
> 1) ? 1 : 2;
365 tegra_plane_writel(plane
, window
->format
, DC_WIN_COLOR_DEPTH
);
366 tegra_plane_writel(plane
, window
->swap
, DC_WIN_BYTE_SWAP
);
368 value
= V_POSITION(window
->dst
.y
) | H_POSITION(window
->dst
.x
);
369 tegra_plane_writel(plane
, value
, DC_WIN_POSITION
);
371 value
= V_SIZE(window
->dst
.h
) | H_SIZE(window
->dst
.w
);
372 tegra_plane_writel(plane
, value
, DC_WIN_SIZE
);
374 h_offset
= window
->src
.x
* bpp
;
375 v_offset
= window
->src
.y
;
376 h_size
= window
->src
.w
* bpp
;
377 v_size
= window
->src
.h
;
379 if (window
->reflect_x
)
380 h_offset
+= (window
->src
.w
- 1) * bpp
;
382 if (window
->reflect_y
)
383 v_offset
+= window
->src
.h
- 1;
385 value
= V_PRESCALED_SIZE(v_size
) | H_PRESCALED_SIZE(h_size
);
386 tegra_plane_writel(plane
, value
, DC_WIN_PRESCALED_SIZE
);
389 * For DDA computations the number of bytes per pixel for YUV planar
390 * modes needs to take into account all Y, U and V components.
392 if (yuv
&& planes
> 1)
395 h_dda
= compute_dda_inc(window
->src
.w
, window
->dst
.w
, false, bpp
);
396 v_dda
= compute_dda_inc(window
->src
.h
, window
->dst
.h
, true, bpp
);
398 value
= V_DDA_INC(v_dda
) | H_DDA_INC(h_dda
);
399 tegra_plane_writel(plane
, value
, DC_WIN_DDA_INC
);
401 h_dda
= compute_initial_dda(window
->src
.x
);
402 v_dda
= compute_initial_dda(window
->src
.y
);
404 tegra_plane_writel(plane
, h_dda
, DC_WIN_H_INITIAL_DDA
);
405 tegra_plane_writel(plane
, v_dda
, DC_WIN_V_INITIAL_DDA
);
407 tegra_plane_writel(plane
, 0, DC_WIN_UV_BUF_STRIDE
);
408 tegra_plane_writel(plane
, 0, DC_WIN_BUF_STRIDE
);
410 tegra_plane_writel(plane
, window
->base
[0], DC_WINBUF_START_ADDR
);
412 if (yuv
&& planes
> 1) {
413 tegra_plane_writel(plane
, window
->base
[1], DC_WINBUF_START_ADDR_U
);
416 tegra_plane_writel(plane
, window
->base
[2], DC_WINBUF_START_ADDR_V
);
418 value
= window
->stride
[1] << 16 | window
->stride
[0];
419 tegra_plane_writel(plane
, value
, DC_WIN_LINE_STRIDE
);
421 tegra_plane_writel(plane
, window
->stride
[0], DC_WIN_LINE_STRIDE
);
424 tegra_plane_writel(plane
, h_offset
, DC_WINBUF_ADDR_H_OFFSET
);
425 tegra_plane_writel(plane
, v_offset
, DC_WINBUF_ADDR_V_OFFSET
);
427 if (dc
->soc
->supports_block_linear
) {
428 unsigned long height
= window
->tiling
.value
;
430 switch (window
->tiling
.mode
) {
431 case TEGRA_BO_TILING_MODE_PITCH
:
432 value
= DC_WINBUF_SURFACE_KIND_PITCH
;
435 case TEGRA_BO_TILING_MODE_TILED
:
436 value
= DC_WINBUF_SURFACE_KIND_TILED
;
439 case TEGRA_BO_TILING_MODE_BLOCK
:
440 value
= DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height
) |
441 DC_WINBUF_SURFACE_KIND_BLOCK
;
445 tegra_plane_writel(plane
, value
, DC_WINBUF_SURFACE_KIND
);
447 switch (window
->tiling
.mode
) {
448 case TEGRA_BO_TILING_MODE_PITCH
:
449 value
= DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV
|
450 DC_WIN_BUFFER_ADDR_MODE_LINEAR
;
453 case TEGRA_BO_TILING_MODE_TILED
:
454 value
= DC_WIN_BUFFER_ADDR_MODE_TILE_UV
|
455 DC_WIN_BUFFER_ADDR_MODE_TILE
;
458 case TEGRA_BO_TILING_MODE_BLOCK
:
460 * No need to handle this here because ->atomic_check
461 * will already have filtered it out.
466 tegra_plane_writel(plane
, value
, DC_WIN_BUFFER_ADDR_MODE
);
472 /* setup default colorspace conversion coefficients */
473 tegra_plane_writel(plane
, 0x00f0, DC_WIN_CSC_YOF
);
474 tegra_plane_writel(plane
, 0x012a, DC_WIN_CSC_KYRGB
);
475 tegra_plane_writel(plane
, 0x0000, DC_WIN_CSC_KUR
);
476 tegra_plane_writel(plane
, 0x0198, DC_WIN_CSC_KVR
);
477 tegra_plane_writel(plane
, 0x039b, DC_WIN_CSC_KUG
);
478 tegra_plane_writel(plane
, 0x032f, DC_WIN_CSC_KVG
);
479 tegra_plane_writel(plane
, 0x0204, DC_WIN_CSC_KUB
);
480 tegra_plane_writel(plane
, 0x0000, DC_WIN_CSC_KVB
);
483 } else if (window
->bits_per_pixel
< 24) {
484 value
|= COLOR_EXPAND
;
487 if (window
->reflect_x
)
488 value
|= H_DIRECTION
;
490 if (window
->reflect_y
)
491 value
|= V_DIRECTION
;
493 if (tegra_plane_use_horizontal_filtering(plane
, window
)) {
495 * Enable horizontal 6-tap filter and set filtering
496 * coefficients to the default values defined in TRM.
498 tegra_plane_writel(plane
, 0x00008000, DC_WIN_H_FILTER_P(0));
499 tegra_plane_writel(plane
, 0x3e087ce1, DC_WIN_H_FILTER_P(1));
500 tegra_plane_writel(plane
, 0x3b117ac1, DC_WIN_H_FILTER_P(2));
501 tegra_plane_writel(plane
, 0x591b73aa, DC_WIN_H_FILTER_P(3));
502 tegra_plane_writel(plane
, 0x57256d9a, DC_WIN_H_FILTER_P(4));
503 tegra_plane_writel(plane
, 0x552f668b, DC_WIN_H_FILTER_P(5));
504 tegra_plane_writel(plane
, 0x73385e8b, DC_WIN_H_FILTER_P(6));
505 tegra_plane_writel(plane
, 0x72435583, DC_WIN_H_FILTER_P(7));
506 tegra_plane_writel(plane
, 0x714c4c8b, DC_WIN_H_FILTER_P(8));
507 tegra_plane_writel(plane
, 0x70554393, DC_WIN_H_FILTER_P(9));
508 tegra_plane_writel(plane
, 0x715e389b, DC_WIN_H_FILTER_P(10));
509 tegra_plane_writel(plane
, 0x71662faa, DC_WIN_H_FILTER_P(11));
510 tegra_plane_writel(plane
, 0x536d25ba, DC_WIN_H_FILTER_P(12));
511 tegra_plane_writel(plane
, 0x55731bca, DC_WIN_H_FILTER_P(13));
512 tegra_plane_writel(plane
, 0x387a11d9, DC_WIN_H_FILTER_P(14));
513 tegra_plane_writel(plane
, 0x3c7c08f1, DC_WIN_H_FILTER_P(15));
518 if (tegra_plane_use_vertical_filtering(plane
, window
)) {
522 * Enable vertical 2-tap filter and set filtering
523 * coefficients to the default values defined in TRM.
525 for (i
= 0, k
= 128; i
< 16; i
++, k
-= 8)
526 tegra_plane_writel(plane
, k
, DC_WIN_V_FILTER_P(i
));
531 tegra_plane_writel(plane
, value
, DC_WIN_WIN_OPTIONS
);
533 if (dc
->soc
->has_legacy_blending
)
534 tegra_plane_setup_blending_legacy(plane
);
536 tegra_plane_setup_blending(plane
, window
);
539 static const u32 tegra20_primary_formats
[] = {
546 /* non-native formats */
553 static const u64 tegra20_modifiers
[] = {
554 DRM_FORMAT_MOD_LINEAR
,
555 DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED
,
556 DRM_FORMAT_MOD_INVALID
559 static const u32 tegra114_primary_formats
[] = {
566 /* new on Tegra114 */
581 static const u32 tegra124_primary_formats
[] = {
588 /* new on Tegra114 */
601 /* new on Tegra124 */
606 static const u64 tegra124_modifiers
[] = {
607 DRM_FORMAT_MOD_LINEAR
,
608 DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0),
609 DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1),
610 DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2),
611 DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3),
612 DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4),
613 DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5),
614 DRM_FORMAT_MOD_INVALID
617 static int tegra_plane_atomic_check(struct drm_plane
*plane
,
618 struct drm_atomic_state
*state
)
620 struct drm_plane_state
*new_plane_state
= drm_atomic_get_new_plane_state(state
,
622 struct tegra_plane_state
*plane_state
= to_tegra_plane_state(new_plane_state
);
623 unsigned int supported_rotation
= DRM_MODE_ROTATE_0
|
626 unsigned int rotation
= new_plane_state
->rotation
;
627 struct tegra_bo_tiling
*tiling
= &plane_state
->tiling
;
628 struct tegra_plane
*tegra
= to_tegra_plane(plane
);
629 struct tegra_dc
*dc
= to_tegra_dc(new_plane_state
->crtc
);
632 plane_state
->peak_memory_bandwidth
= 0;
633 plane_state
->avg_memory_bandwidth
= 0;
635 /* no need for further checks if the plane is being disabled */
636 if (!new_plane_state
->crtc
) {
637 plane_state
->total_peak_memory_bandwidth
= 0;
641 err
= tegra_plane_format(new_plane_state
->fb
->format
->format
,
642 &plane_state
->format
,
648 * Tegra20 and Tegra30 are special cases here because they support
649 * only variants of specific formats with an alpha component, but not
650 * the corresponding opaque formats. However, the opaque formats can
651 * be emulated by disabling alpha blending for the plane.
653 if (dc
->soc
->has_legacy_blending
) {
654 err
= tegra_plane_setup_legacy_state(tegra
, plane_state
);
659 err
= tegra_fb_get_tiling(new_plane_state
->fb
, tiling
);
663 if (tiling
->mode
== TEGRA_BO_TILING_MODE_BLOCK
&&
664 !dc
->soc
->supports_block_linear
) {
665 DRM_ERROR("hardware doesn't support block linear mode\n");
670 * Older userspace used custom BO flag in order to specify the Y
671 * reflection, while modern userspace uses the generic DRM rotation
672 * property in order to achieve the same result. The legacy BO flag
673 * duplicates the DRM rotation property when both are set.
675 if (tegra_fb_is_bottom_up(new_plane_state
->fb
))
676 rotation
|= DRM_MODE_REFLECT_Y
;
678 rotation
= drm_rotation_simplify(rotation
, supported_rotation
);
680 if (rotation
& DRM_MODE_REFLECT_X
)
681 plane_state
->reflect_x
= true;
683 plane_state
->reflect_x
= false;
685 if (rotation
& DRM_MODE_REFLECT_Y
)
686 plane_state
->reflect_y
= true;
688 plane_state
->reflect_y
= false;
691 * Tegra doesn't support different strides for U and V planes so we
692 * error out if the user tries to display a framebuffer with such a
695 if (new_plane_state
->fb
->format
->num_planes
> 2) {
696 if (new_plane_state
->fb
->pitches
[2] != new_plane_state
->fb
->pitches
[1]) {
697 DRM_ERROR("unsupported UV-plane configuration\n");
702 err
= tegra_plane_state_add(tegra
, new_plane_state
);
709 static void tegra_plane_atomic_disable(struct drm_plane
*plane
,
710 struct drm_atomic_state
*state
)
712 struct drm_plane_state
*old_state
= drm_atomic_get_old_plane_state(state
,
714 struct tegra_plane
*p
= to_tegra_plane(plane
);
717 /* rien ne va plus */
718 if (!old_state
|| !old_state
->crtc
)
721 value
= tegra_plane_readl(p
, DC_WIN_WIN_OPTIONS
);
722 value
&= ~WIN_ENABLE
;
723 tegra_plane_writel(p
, value
, DC_WIN_WIN_OPTIONS
);
726 static void tegra_plane_atomic_update(struct drm_plane
*plane
,
727 struct drm_atomic_state
*state
)
729 struct drm_plane_state
*new_state
= drm_atomic_get_new_plane_state(state
,
731 struct tegra_plane_state
*tegra_plane_state
= to_tegra_plane_state(new_state
);
732 struct drm_framebuffer
*fb
= new_state
->fb
;
733 struct tegra_plane
*p
= to_tegra_plane(plane
);
734 struct tegra_dc_window window
;
737 /* rien ne va plus */
738 if (!new_state
->crtc
|| !new_state
->fb
)
741 if (!new_state
->visible
)
742 return tegra_plane_atomic_disable(plane
, state
);
744 memset(&window
, 0, sizeof(window
));
745 window
.src
.x
= new_state
->src
.x1
>> 16;
746 window
.src
.y
= new_state
->src
.y1
>> 16;
747 window
.src
.w
= drm_rect_width(&new_state
->src
) >> 16;
748 window
.src
.h
= drm_rect_height(&new_state
->src
) >> 16;
749 window
.dst
.x
= new_state
->dst
.x1
;
750 window
.dst
.y
= new_state
->dst
.y1
;
751 window
.dst
.w
= drm_rect_width(&new_state
->dst
);
752 window
.dst
.h
= drm_rect_height(&new_state
->dst
);
753 window
.bits_per_pixel
= fb
->format
->cpp
[0] * 8;
754 window
.reflect_x
= tegra_plane_state
->reflect_x
;
755 window
.reflect_y
= tegra_plane_state
->reflect_y
;
757 /* copy from state */
758 window
.zpos
= new_state
->normalized_zpos
;
759 window
.tiling
= tegra_plane_state
->tiling
;
760 window
.format
= tegra_plane_state
->format
;
761 window
.swap
= tegra_plane_state
->swap
;
763 for (i
= 0; i
< fb
->format
->num_planes
; i
++) {
764 window
.base
[i
] = tegra_plane_state
->iova
[i
] + fb
->offsets
[i
];
767 * Tegra uses a shared stride for UV planes. Framebuffers are
768 * already checked for this in the tegra_plane_atomic_check()
769 * function, so it's safe to ignore the V-plane pitch here.
772 window
.stride
[i
] = fb
->pitches
[i
];
775 tegra_dc_setup_window(p
, &window
);
778 static const struct drm_plane_helper_funcs tegra_plane_helper_funcs
= {
779 .prepare_fb
= tegra_plane_prepare_fb
,
780 .cleanup_fb
= tegra_plane_cleanup_fb
,
781 .atomic_check
= tegra_plane_atomic_check
,
782 .atomic_disable
= tegra_plane_atomic_disable
,
783 .atomic_update
= tegra_plane_atomic_update
,
786 static unsigned long tegra_plane_get_possible_crtcs(struct drm_device
*drm
)
789 * Ideally this would use drm_crtc_mask(), but that would require the
790 * CRTC to already be in the mode_config's list of CRTCs. However, it
791 * will only be added to that list in the drm_crtc_init_with_planes()
792 * (in tegra_dc_init()), which in turn requires registration of these
793 * planes. So we have ourselves a nice little chicken and egg problem
796 * We work around this by manually creating the mask from the number
797 * of CRTCs that have been registered, and should therefore always be
798 * the same as drm_crtc_index() after registration.
800 return 1 << drm
->mode_config
.num_crtc
;
803 static struct drm_plane
*tegra_primary_plane_create(struct drm_device
*drm
,
806 unsigned long possible_crtcs
= tegra_plane_get_possible_crtcs(drm
);
807 enum drm_plane_type type
= DRM_PLANE_TYPE_PRIMARY
;
808 struct tegra_plane
*plane
;
809 unsigned int num_formats
;
810 const u64
*modifiers
;
814 plane
= kzalloc(sizeof(*plane
), GFP_KERNEL
);
816 return ERR_PTR(-ENOMEM
);
818 /* Always use window A as primary window */
819 plane
->offset
= 0xa00;
823 num_formats
= dc
->soc
->num_primary_formats
;
824 formats
= dc
->soc
->primary_formats
;
825 modifiers
= dc
->soc
->modifiers
;
827 err
= tegra_plane_interconnect_init(plane
);
833 err
= drm_universal_plane_init(drm
, &plane
->base
, possible_crtcs
,
834 &tegra_plane_funcs
, formats
,
835 num_formats
, modifiers
, type
, NULL
);
841 drm_plane_helper_add(&plane
->base
, &tegra_plane_helper_funcs
);
842 drm_plane_create_zpos_property(&plane
->base
, plane
->index
, 0, 255);
844 err
= drm_plane_create_rotation_property(&plane
->base
,
847 DRM_MODE_ROTATE_180
|
851 dev_err(dc
->dev
, "failed to create rotation property: %d\n",
857 static const u32 tegra_legacy_cursor_plane_formats
[] = {
861 static const u32 tegra_cursor_plane_formats
[] = {
865 static int tegra_cursor_atomic_check(struct drm_plane
*plane
,
866 struct drm_atomic_state
*state
)
868 struct drm_plane_state
*new_plane_state
= drm_atomic_get_new_plane_state(state
,
870 struct tegra_plane_state
*plane_state
= to_tegra_plane_state(new_plane_state
);
871 struct tegra_plane
*tegra
= to_tegra_plane(plane
);
874 plane_state
->peak_memory_bandwidth
= 0;
875 plane_state
->avg_memory_bandwidth
= 0;
877 /* no need for further checks if the plane is being disabled */
878 if (!new_plane_state
->crtc
) {
879 plane_state
->total_peak_memory_bandwidth
= 0;
883 /* scaling not supported for cursor */
884 if ((new_plane_state
->src_w
>> 16 != new_plane_state
->crtc_w
) ||
885 (new_plane_state
->src_h
>> 16 != new_plane_state
->crtc_h
))
888 /* only square cursors supported */
889 if (new_plane_state
->src_w
!= new_plane_state
->src_h
)
892 if (new_plane_state
->crtc_w
!= 32 && new_plane_state
->crtc_w
!= 64 &&
893 new_plane_state
->crtc_w
!= 128 && new_plane_state
->crtc_w
!= 256)
896 err
= tegra_plane_state_add(tegra
, new_plane_state
);
903 static void __tegra_cursor_atomic_update(struct drm_plane
*plane
,
904 struct drm_plane_state
*new_state
)
906 struct tegra_plane_state
*tegra_plane_state
= to_tegra_plane_state(new_state
);
907 struct tegra_dc
*dc
= to_tegra_dc(new_state
->crtc
);
908 struct tegra_drm
*tegra
= plane
->dev
->dev_private
;
909 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
910 u64 dma_mask
= *dc
->dev
->dma_mask
;
915 /* rien ne va plus */
916 if (!new_state
->crtc
|| !new_state
->fb
)
920 * Legacy display supports hardware clipping of the cursor, but
921 * nvdisplay relies on software to clip the cursor to the screen.
923 if (!dc
->soc
->has_nvdisplay
)
924 value
|= CURSOR_CLIP_DISPLAY
;
926 switch (new_state
->crtc_w
) {
928 value
|= CURSOR_SIZE_32x32
;
932 value
|= CURSOR_SIZE_64x64
;
936 value
|= CURSOR_SIZE_128x128
;
940 value
|= CURSOR_SIZE_256x256
;
944 WARN(1, "cursor size %ux%u not supported\n",
945 new_state
->crtc_w
, new_state
->crtc_h
);
949 value
|= (tegra_plane_state
->iova
[0] >> 10) & 0x3fffff;
950 tegra_dc_writel(dc
, value
, DC_DISP_CURSOR_START_ADDR
);
952 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
953 value
= (tegra_plane_state
->iova
[0] >> 32) & (dma_mask
>> 32);
954 tegra_dc_writel(dc
, value
, DC_DISP_CURSOR_START_ADDR_HI
);
957 /* enable cursor and set blend mode */
958 value
= tegra_dc_readl(dc
, DC_DISP_DISP_WIN_OPTIONS
);
959 value
|= CURSOR_ENABLE
;
960 tegra_dc_writel(dc
, value
, DC_DISP_DISP_WIN_OPTIONS
);
962 value
= tegra_dc_readl(dc
, DC_DISP_BLEND_CURSOR_CONTROL
);
963 value
&= ~CURSOR_DST_BLEND_MASK
;
964 value
&= ~CURSOR_SRC_BLEND_MASK
;
966 if (dc
->soc
->has_nvdisplay
)
967 value
&= ~CURSOR_COMPOSITION_MODE_XOR
;
969 value
|= CURSOR_MODE_NORMAL
;
971 value
|= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC
;
972 value
|= CURSOR_SRC_BLEND_K1_TIMES_SRC
;
973 value
|= CURSOR_ALPHA
;
974 tegra_dc_writel(dc
, value
, DC_DISP_BLEND_CURSOR_CONTROL
);
976 /* nvdisplay relies on software for clipping */
977 if (dc
->soc
->has_nvdisplay
) {
980 x
= new_state
->dst
.x1
;
981 y
= new_state
->dst
.y1
;
983 drm_rect_fp_to_int(&src
, &new_state
->src
);
985 value
= (src
.y1
& tegra
->vmask
) << 16 | (src
.x1
& tegra
->hmask
);
986 tegra_dc_writel(dc
, value
, DC_DISP_PCALC_HEAD_SET_CROPPED_POINT_IN_CURSOR
);
988 value
= (drm_rect_height(&src
) & tegra
->vmask
) << 16 |
989 (drm_rect_width(&src
) & tegra
->hmask
);
990 tegra_dc_writel(dc
, value
, DC_DISP_PCALC_HEAD_SET_CROPPED_SIZE_IN_CURSOR
);
992 x
= new_state
->crtc_x
;
993 y
= new_state
->crtc_y
;
996 /* position the cursor */
997 value
= ((y
& tegra
->vmask
) << 16) | (x
& tegra
->hmask
);
998 tegra_dc_writel(dc
, value
, DC_DISP_CURSOR_POSITION
);
1001 static void tegra_cursor_atomic_update(struct drm_plane
*plane
,
1002 struct drm_atomic_state
*state
)
1004 struct drm_plane_state
*new_state
= drm_atomic_get_new_plane_state(state
, plane
);
1006 __tegra_cursor_atomic_update(plane
, new_state
);
1009 static void tegra_cursor_atomic_disable(struct drm_plane
*plane
,
1010 struct drm_atomic_state
*state
)
1012 struct drm_plane_state
*old_state
= drm_atomic_get_old_plane_state(state
,
1014 struct tegra_dc
*dc
;
1017 /* rien ne va plus */
1018 if (!old_state
|| !old_state
->crtc
)
1021 dc
= to_tegra_dc(old_state
->crtc
);
1023 value
= tegra_dc_readl(dc
, DC_DISP_DISP_WIN_OPTIONS
);
1024 value
&= ~CURSOR_ENABLE
;
1025 tegra_dc_writel(dc
, value
, DC_DISP_DISP_WIN_OPTIONS
);
1028 static int tegra_cursor_atomic_async_check(struct drm_plane
*plane
, struct drm_atomic_state
*state
)
1030 struct drm_plane_state
*new_state
= drm_atomic_get_new_plane_state(state
, plane
);
1031 struct drm_crtc_state
*crtc_state
;
1032 int min_scale
, max_scale
;
1035 crtc_state
= drm_atomic_get_existing_crtc_state(state
, new_state
->crtc
);
1036 if (WARN_ON(!crtc_state
))
1039 if (!crtc_state
->active
)
1042 if (plane
->state
->crtc
!= new_state
->crtc
||
1043 plane
->state
->src_w
!= new_state
->src_w
||
1044 plane
->state
->src_h
!= new_state
->src_h
||
1045 plane
->state
->crtc_w
!= new_state
->crtc_w
||
1046 plane
->state
->crtc_h
!= new_state
->crtc_h
||
1047 plane
->state
->fb
!= new_state
->fb
||
1048 plane
->state
->fb
== NULL
)
1051 min_scale
= (1 << 16) / 8;
1052 max_scale
= (8 << 16) / 1;
1054 err
= drm_atomic_helper_check_plane_state(new_state
, crtc_state
, min_scale
, max_scale
,
1059 if (new_state
->visible
!= plane
->state
->visible
)
1065 static void tegra_cursor_atomic_async_update(struct drm_plane
*plane
,
1066 struct drm_atomic_state
*state
)
1068 struct drm_plane_state
*new_state
= drm_atomic_get_new_plane_state(state
, plane
);
1069 struct tegra_dc
*dc
= to_tegra_dc(new_state
->crtc
);
1071 plane
->state
->src_x
= new_state
->src_x
;
1072 plane
->state
->src_y
= new_state
->src_y
;
1073 plane
->state
->crtc_x
= new_state
->crtc_x
;
1074 plane
->state
->crtc_y
= new_state
->crtc_y
;
1076 if (new_state
->visible
) {
1077 struct tegra_plane
*p
= to_tegra_plane(plane
);
1080 __tegra_cursor_atomic_update(plane
, new_state
);
1082 value
= (WIN_A_ACT_REQ
<< p
->index
) << 8 | GENERAL_UPDATE
;
1083 tegra_dc_writel(dc
, value
, DC_CMD_STATE_CONTROL
);
1084 (void)tegra_dc_readl(dc
, DC_CMD_STATE_CONTROL
);
1086 value
= (WIN_A_ACT_REQ
<< p
->index
) | GENERAL_ACT_REQ
;
1087 tegra_dc_writel(dc
, value
, DC_CMD_STATE_CONTROL
);
1088 (void)tegra_dc_readl(dc
, DC_CMD_STATE_CONTROL
);
1092 static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs
= {
1093 .prepare_fb
= tegra_plane_prepare_fb
,
1094 .cleanup_fb
= tegra_plane_cleanup_fb
,
1095 .atomic_check
= tegra_cursor_atomic_check
,
1096 .atomic_update
= tegra_cursor_atomic_update
,
1097 .atomic_disable
= tegra_cursor_atomic_disable
,
1098 .atomic_async_check
= tegra_cursor_atomic_async_check
,
1099 .atomic_async_update
= tegra_cursor_atomic_async_update
,
1102 static const uint64_t linear_modifiers
[] = {
1103 DRM_FORMAT_MOD_LINEAR
,
1104 DRM_FORMAT_MOD_INVALID
1107 static struct drm_plane
*tegra_dc_cursor_plane_create(struct drm_device
*drm
,
1108 struct tegra_dc
*dc
)
1110 unsigned long possible_crtcs
= tegra_plane_get_possible_crtcs(drm
);
1111 struct tegra_plane
*plane
;
1112 unsigned int num_formats
;
1116 plane
= kzalloc(sizeof(*plane
), GFP_KERNEL
);
1118 return ERR_PTR(-ENOMEM
);
1121 * This index is kind of fake. The cursor isn't a regular plane, but
1122 * its update and activation request bits in DC_CMD_STATE_CONTROL do
1123 * use the same programming. Setting this fake index here allows the
1124 * code in tegra_add_plane_state() to do the right thing without the
1125 * need to special-casing the cursor plane.
1130 if (!dc
->soc
->has_nvdisplay
) {
1131 num_formats
= ARRAY_SIZE(tegra_legacy_cursor_plane_formats
);
1132 formats
= tegra_legacy_cursor_plane_formats
;
1134 err
= tegra_plane_interconnect_init(plane
);
1137 return ERR_PTR(err
);
1140 num_formats
= ARRAY_SIZE(tegra_cursor_plane_formats
);
1141 formats
= tegra_cursor_plane_formats
;
1144 err
= drm_universal_plane_init(drm
, &plane
->base
, possible_crtcs
,
1145 &tegra_plane_funcs
, formats
,
1146 num_formats
, linear_modifiers
,
1147 DRM_PLANE_TYPE_CURSOR
, NULL
);
1150 return ERR_PTR(err
);
1153 drm_plane_helper_add(&plane
->base
, &tegra_cursor_plane_helper_funcs
);
1154 drm_plane_create_zpos_immutable_property(&plane
->base
, 255);
1156 return &plane
->base
;
1159 static const u32 tegra20_overlay_formats
[] = {
1160 DRM_FORMAT_ARGB4444
,
1161 DRM_FORMAT_ARGB1555
,
1163 DRM_FORMAT_RGBA5551
,
1164 DRM_FORMAT_ABGR8888
,
1165 DRM_FORMAT_ARGB8888
,
1166 /* non-native formats */
1167 DRM_FORMAT_XRGB1555
,
1168 DRM_FORMAT_RGBX5551
,
1169 DRM_FORMAT_XBGR8888
,
1170 DRM_FORMAT_XRGB8888
,
1171 /* planar formats */
1178 static const u32 tegra114_overlay_formats
[] = {
1179 DRM_FORMAT_ARGB4444
,
1180 DRM_FORMAT_ARGB1555
,
1182 DRM_FORMAT_RGBA5551
,
1183 DRM_FORMAT_ABGR8888
,
1184 DRM_FORMAT_ARGB8888
,
1185 /* new on Tegra114 */
1186 DRM_FORMAT_ABGR4444
,
1187 DRM_FORMAT_ABGR1555
,
1188 DRM_FORMAT_BGRA5551
,
1189 DRM_FORMAT_XRGB1555
,
1190 DRM_FORMAT_RGBX5551
,
1191 DRM_FORMAT_XBGR1555
,
1192 DRM_FORMAT_BGRX5551
,
1194 DRM_FORMAT_BGRA8888
,
1195 DRM_FORMAT_RGBA8888
,
1196 DRM_FORMAT_XRGB8888
,
1197 DRM_FORMAT_XBGR8888
,
1198 /* planar formats */
1203 /* semi-planar formats */
1212 static const u32 tegra124_overlay_formats
[] = {
1213 DRM_FORMAT_ARGB4444
,
1214 DRM_FORMAT_ARGB1555
,
1216 DRM_FORMAT_RGBA5551
,
1217 DRM_FORMAT_ABGR8888
,
1218 DRM_FORMAT_ARGB8888
,
1219 /* new on Tegra114 */
1220 DRM_FORMAT_ABGR4444
,
1221 DRM_FORMAT_ABGR1555
,
1222 DRM_FORMAT_BGRA5551
,
1223 DRM_FORMAT_XRGB1555
,
1224 DRM_FORMAT_RGBX5551
,
1225 DRM_FORMAT_XBGR1555
,
1226 DRM_FORMAT_BGRX5551
,
1228 DRM_FORMAT_BGRA8888
,
1229 DRM_FORMAT_RGBA8888
,
1230 DRM_FORMAT_XRGB8888
,
1231 DRM_FORMAT_XBGR8888
,
1232 /* new on Tegra124 */
1233 DRM_FORMAT_RGBX8888
,
1234 DRM_FORMAT_BGRX8888
,
1235 /* planar formats */
1240 DRM_FORMAT_YUV420
, /* YU12 */
1241 DRM_FORMAT_YUV422
, /* YU16 */
1242 DRM_FORMAT_YUV444
, /* YU24 */
1243 /* semi-planar formats */
1252 static struct drm_plane
*tegra_dc_overlay_plane_create(struct drm_device
*drm
,
1253 struct tegra_dc
*dc
,
1257 unsigned long possible_crtcs
= tegra_plane_get_possible_crtcs(drm
);
1258 struct tegra_plane
*plane
;
1259 unsigned int num_formats
;
1260 enum drm_plane_type type
;
1264 plane
= kzalloc(sizeof(*plane
), GFP_KERNEL
);
1266 return ERR_PTR(-ENOMEM
);
1268 plane
->offset
= 0xa00 + 0x200 * index
;
1269 plane
->index
= index
;
1272 num_formats
= dc
->soc
->num_overlay_formats
;
1273 formats
= dc
->soc
->overlay_formats
;
1275 err
= tegra_plane_interconnect_init(plane
);
1278 return ERR_PTR(err
);
1282 type
= DRM_PLANE_TYPE_OVERLAY
;
1284 type
= DRM_PLANE_TYPE_CURSOR
;
1286 err
= drm_universal_plane_init(drm
, &plane
->base
, possible_crtcs
,
1287 &tegra_plane_funcs
, formats
,
1288 num_formats
, linear_modifiers
,
1292 return ERR_PTR(err
);
1295 drm_plane_helper_add(&plane
->base
, &tegra_plane_helper_funcs
);
1296 drm_plane_create_zpos_property(&plane
->base
, plane
->index
, 0, 255);
1298 err
= drm_plane_create_rotation_property(&plane
->base
,
1301 DRM_MODE_ROTATE_180
|
1302 DRM_MODE_REFLECT_X
|
1303 DRM_MODE_REFLECT_Y
);
1305 dev_err(dc
->dev
, "failed to create rotation property: %d\n",
1308 return &plane
->base
;
1311 static struct drm_plane
*tegra_dc_add_shared_planes(struct drm_device
*drm
,
1312 struct tegra_dc
*dc
)
1314 struct drm_plane
*plane
, *primary
= NULL
;
1317 for (i
= 0; i
< dc
->soc
->num_wgrps
; i
++) {
1318 const struct tegra_windowgroup_soc
*wgrp
= &dc
->soc
->wgrps
[i
];
1320 if (wgrp
->dc
== dc
->pipe
) {
1321 for (j
= 0; j
< wgrp
->num_windows
; j
++) {
1322 unsigned int index
= wgrp
->windows
[j
];
1324 plane
= tegra_shared_plane_create(drm
, dc
,
1331 * Choose the first shared plane owned by this
1332 * head as the primary plane.
1335 plane
->type
= DRM_PLANE_TYPE_PRIMARY
;
1345 static struct drm_plane
*tegra_dc_add_planes(struct drm_device
*drm
,
1346 struct tegra_dc
*dc
)
1348 struct drm_plane
*planes
[2], *primary
;
1349 unsigned int planes_num
;
1353 primary
= tegra_primary_plane_create(drm
, dc
);
1354 if (IS_ERR(primary
))
1357 if (dc
->soc
->supports_cursor
)
1362 for (i
= 0; i
< planes_num
; i
++) {
1363 planes
[i
] = tegra_dc_overlay_plane_create(drm
, dc
, 1 + i
,
1365 if (IS_ERR(planes
[i
])) {
1366 err
= PTR_ERR(planes
[i
]);
1369 planes
[i
]->funcs
->destroy(planes
[i
]);
1371 primary
->funcs
->destroy(primary
);
1372 return ERR_PTR(err
);
1379 static void tegra_dc_destroy(struct drm_crtc
*crtc
)
1381 drm_crtc_cleanup(crtc
);
1384 static void tegra_crtc_reset(struct drm_crtc
*crtc
)
1386 struct tegra_dc_state
*state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
1389 tegra_crtc_atomic_destroy_state(crtc
, crtc
->state
);
1391 __drm_atomic_helper_crtc_reset(crtc
, &state
->base
);
1394 static struct drm_crtc_state
*
1395 tegra_crtc_atomic_duplicate_state(struct drm_crtc
*crtc
)
1397 struct tegra_dc_state
*state
= to_dc_state(crtc
->state
);
1398 struct tegra_dc_state
*copy
;
1400 copy
= kmalloc(sizeof(*copy
), GFP_KERNEL
);
1404 __drm_atomic_helper_crtc_duplicate_state(crtc
, ©
->base
);
1405 copy
->clk
= state
->clk
;
1406 copy
->pclk
= state
->pclk
;
1407 copy
->div
= state
->div
;
1408 copy
->planes
= state
->planes
;
1413 static void tegra_crtc_atomic_destroy_state(struct drm_crtc
*crtc
,
1414 struct drm_crtc_state
*state
)
1416 __drm_atomic_helper_crtc_destroy_state(state
);
1420 #define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
1422 static const struct debugfs_reg32 tegra_dc_regs
[] = {
1423 DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT
),
1424 DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL
),
1425 DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_ERROR
),
1426 DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT
),
1427 DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL
),
1428 DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_ERROR
),
1429 DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT
),
1430 DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL
),
1431 DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_ERROR
),
1432 DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT
),
1433 DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL
),
1434 DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_ERROR
),
1435 DEBUGFS_REG32(DC_CMD_CONT_SYNCPT_VSYNC
),
1436 DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND_OPTION0
),
1437 DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND
),
1438 DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE
),
1439 DEBUGFS_REG32(DC_CMD_DISPLAY_POWER_CONTROL
),
1440 DEBUGFS_REG32(DC_CMD_INT_STATUS
),
1441 DEBUGFS_REG32(DC_CMD_INT_MASK
),
1442 DEBUGFS_REG32(DC_CMD_INT_ENABLE
),
1443 DEBUGFS_REG32(DC_CMD_INT_TYPE
),
1444 DEBUGFS_REG32(DC_CMD_INT_POLARITY
),
1445 DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE1
),
1446 DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE2
),
1447 DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE3
),
1448 DEBUGFS_REG32(DC_CMD_STATE_ACCESS
),
1449 DEBUGFS_REG32(DC_CMD_STATE_CONTROL
),
1450 DEBUGFS_REG32(DC_CMD_DISPLAY_WINDOW_HEADER
),
1451 DEBUGFS_REG32(DC_CMD_REG_ACT_CONTROL
),
1452 DEBUGFS_REG32(DC_COM_CRC_CONTROL
),
1453 DEBUGFS_REG32(DC_COM_CRC_CHECKSUM
),
1454 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(0)),
1455 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(1)),
1456 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(2)),
1457 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(3)),
1458 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(0)),
1459 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(1)),
1460 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(2)),
1461 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(3)),
1462 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(0)),
1463 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(1)),
1464 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(2)),
1465 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(3)),
1466 DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(0)),
1467 DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(1)),
1468 DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(2)),
1469 DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(3)),
1470 DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(0)),
1471 DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(1)),
1472 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(0)),
1473 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(1)),
1474 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(2)),
1475 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(3)),
1476 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(4)),
1477 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(5)),
1478 DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(6)),
1479 DEBUGFS_REG32(DC_COM_PIN_MISC_CONTROL
),
1480 DEBUGFS_REG32(DC_COM_PIN_PM0_CONTROL
),
1481 DEBUGFS_REG32(DC_COM_PIN_PM0_DUTY_CYCLE
),
1482 DEBUGFS_REG32(DC_COM_PIN_PM1_CONTROL
),
1483 DEBUGFS_REG32(DC_COM_PIN_PM1_DUTY_CYCLE
),
1484 DEBUGFS_REG32(DC_COM_SPI_CONTROL
),
1485 DEBUGFS_REG32(DC_COM_SPI_START_BYTE
),
1486 DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_AB
),
1487 DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_CD
),
1488 DEBUGFS_REG32(DC_COM_HSPI_CS_DC
),
1489 DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_A
),
1490 DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_B
),
1491 DEBUGFS_REG32(DC_COM_GPIO_CTRL
),
1492 DEBUGFS_REG32(DC_COM_GPIO_DEBOUNCE_COUNTER
),
1493 DEBUGFS_REG32(DC_COM_CRC_CHECKSUM_LATCHED
),
1494 DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS0
),
1495 DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS1
),
1496 DEBUGFS_REG32(DC_DISP_DISP_WIN_OPTIONS
),
1497 DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY
),
1498 DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER
),
1499 DEBUGFS_REG32(DC_DISP_DISP_TIMING_OPTIONS
),
1500 DEBUGFS_REG32(DC_DISP_REF_TO_SYNC
),
1501 DEBUGFS_REG32(DC_DISP_SYNC_WIDTH
),
1502 DEBUGFS_REG32(DC_DISP_BACK_PORCH
),
1503 DEBUGFS_REG32(DC_DISP_ACTIVE
),
1504 DEBUGFS_REG32(DC_DISP_FRONT_PORCH
),
1505 DEBUGFS_REG32(DC_DISP_H_PULSE0_CONTROL
),
1506 DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_A
),
1507 DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_B
),
1508 DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_C
),
1509 DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_D
),
1510 DEBUGFS_REG32(DC_DISP_H_PULSE1_CONTROL
),
1511 DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_A
),
1512 DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_B
),
1513 DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_C
),
1514 DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_D
),
1515 DEBUGFS_REG32(DC_DISP_H_PULSE2_CONTROL
),
1516 DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_A
),
1517 DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_B
),
1518 DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_C
),
1519 DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_D
),
1520 DEBUGFS_REG32(DC_DISP_V_PULSE0_CONTROL
),
1521 DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_A
),
1522 DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_B
),
1523 DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_C
),
1524 DEBUGFS_REG32(DC_DISP_V_PULSE1_CONTROL
),
1525 DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_A
),
1526 DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_B
),
1527 DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_C
),
1528 DEBUGFS_REG32(DC_DISP_V_PULSE2_CONTROL
),
1529 DEBUGFS_REG32(DC_DISP_V_PULSE2_POSITION_A
),
1530 DEBUGFS_REG32(DC_DISP_V_PULSE3_CONTROL
),
1531 DEBUGFS_REG32(DC_DISP_V_PULSE3_POSITION_A
),
1532 DEBUGFS_REG32(DC_DISP_M0_CONTROL
),
1533 DEBUGFS_REG32(DC_DISP_M1_CONTROL
),
1534 DEBUGFS_REG32(DC_DISP_DI_CONTROL
),
1535 DEBUGFS_REG32(DC_DISP_PP_CONTROL
),
1536 DEBUGFS_REG32(DC_DISP_PP_SELECT_A
),
1537 DEBUGFS_REG32(DC_DISP_PP_SELECT_B
),
1538 DEBUGFS_REG32(DC_DISP_PP_SELECT_C
),
1539 DEBUGFS_REG32(DC_DISP_PP_SELECT_D
),
1540 DEBUGFS_REG32(DC_DISP_DISP_CLOCK_CONTROL
),
1541 DEBUGFS_REG32(DC_DISP_DISP_INTERFACE_CONTROL
),
1542 DEBUGFS_REG32(DC_DISP_DISP_COLOR_CONTROL
),
1543 DEBUGFS_REG32(DC_DISP_SHIFT_CLOCK_OPTIONS
),
1544 DEBUGFS_REG32(DC_DISP_DATA_ENABLE_OPTIONS
),
1545 DEBUGFS_REG32(DC_DISP_SERIAL_INTERFACE_OPTIONS
),
1546 DEBUGFS_REG32(DC_DISP_LCD_SPI_OPTIONS
),
1547 DEBUGFS_REG32(DC_DISP_BORDER_COLOR
),
1548 DEBUGFS_REG32(DC_DISP_COLOR_KEY0_LOWER
),
1549 DEBUGFS_REG32(DC_DISP_COLOR_KEY0_UPPER
),
1550 DEBUGFS_REG32(DC_DISP_COLOR_KEY1_LOWER
),
1551 DEBUGFS_REG32(DC_DISP_COLOR_KEY1_UPPER
),
1552 DEBUGFS_REG32(DC_DISP_CURSOR_FOREGROUND
),
1553 DEBUGFS_REG32(DC_DISP_CURSOR_BACKGROUND
),
1554 DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR
),
1555 DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_NS
),
1556 DEBUGFS_REG32(DC_DISP_CURSOR_POSITION
),
1557 DEBUGFS_REG32(DC_DISP_CURSOR_POSITION_NS
),
1558 DEBUGFS_REG32(DC_DISP_INIT_SEQ_CONTROL
),
1559 DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_A
),
1560 DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_B
),
1561 DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_C
),
1562 DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_D
),
1563 DEBUGFS_REG32(DC_DISP_DC_MCCIF_FIFOCTRL
),
1564 DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0A_HYST
),
1565 DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0B_HYST
),
1566 DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1A_HYST
),
1567 DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1B_HYST
),
1568 DEBUGFS_REG32(DC_DISP_DAC_CRT_CTRL
),
1569 DEBUGFS_REG32(DC_DISP_DISP_MISC_CONTROL
),
1570 DEBUGFS_REG32(DC_DISP_SD_CONTROL
),
1571 DEBUGFS_REG32(DC_DISP_SD_CSC_COEFF
),
1572 DEBUGFS_REG32(DC_DISP_SD_LUT(0)),
1573 DEBUGFS_REG32(DC_DISP_SD_LUT(1)),
1574 DEBUGFS_REG32(DC_DISP_SD_LUT(2)),
1575 DEBUGFS_REG32(DC_DISP_SD_LUT(3)),
1576 DEBUGFS_REG32(DC_DISP_SD_LUT(4)),
1577 DEBUGFS_REG32(DC_DISP_SD_LUT(5)),
1578 DEBUGFS_REG32(DC_DISP_SD_LUT(6)),
1579 DEBUGFS_REG32(DC_DISP_SD_LUT(7)),
1580 DEBUGFS_REG32(DC_DISP_SD_LUT(8)),
1581 DEBUGFS_REG32(DC_DISP_SD_FLICKER_CONTROL
),
1582 DEBUGFS_REG32(DC_DISP_DC_PIXEL_COUNT
),
1583 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(0)),
1584 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(1)),
1585 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(2)),
1586 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(3)),
1587 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(4)),
1588 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(5)),
1589 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(6)),
1590 DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(7)),
1591 DEBUGFS_REG32(DC_DISP_SD_BL_TF(0)),
1592 DEBUGFS_REG32(DC_DISP_SD_BL_TF(1)),
1593 DEBUGFS_REG32(DC_DISP_SD_BL_TF(2)),
1594 DEBUGFS_REG32(DC_DISP_SD_BL_TF(3)),
1595 DEBUGFS_REG32(DC_DISP_SD_BL_CONTROL
),
1596 DEBUGFS_REG32(DC_DISP_SD_HW_K_VALUES
),
1597 DEBUGFS_REG32(DC_DISP_SD_MAN_K_VALUES
),
1598 DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_HI
),
1599 DEBUGFS_REG32(DC_DISP_BLEND_CURSOR_CONTROL
),
1600 DEBUGFS_REG32(DC_WIN_WIN_OPTIONS
),
1601 DEBUGFS_REG32(DC_WIN_BYTE_SWAP
),
1602 DEBUGFS_REG32(DC_WIN_BUFFER_CONTROL
),
1603 DEBUGFS_REG32(DC_WIN_COLOR_DEPTH
),
1604 DEBUGFS_REG32(DC_WIN_POSITION
),
1605 DEBUGFS_REG32(DC_WIN_SIZE
),
1606 DEBUGFS_REG32(DC_WIN_PRESCALED_SIZE
),
1607 DEBUGFS_REG32(DC_WIN_H_INITIAL_DDA
),
1608 DEBUGFS_REG32(DC_WIN_V_INITIAL_DDA
),
1609 DEBUGFS_REG32(DC_WIN_DDA_INC
),
1610 DEBUGFS_REG32(DC_WIN_LINE_STRIDE
),
1611 DEBUGFS_REG32(DC_WIN_BUF_STRIDE
),
1612 DEBUGFS_REG32(DC_WIN_UV_BUF_STRIDE
),
1613 DEBUGFS_REG32(DC_WIN_BUFFER_ADDR_MODE
),
1614 DEBUGFS_REG32(DC_WIN_DV_CONTROL
),
1615 DEBUGFS_REG32(DC_WIN_BLEND_NOKEY
),
1616 DEBUGFS_REG32(DC_WIN_BLEND_1WIN
),
1617 DEBUGFS_REG32(DC_WIN_BLEND_2WIN_X
),
1618 DEBUGFS_REG32(DC_WIN_BLEND_2WIN_Y
),
1619 DEBUGFS_REG32(DC_WIN_BLEND_3WIN_XY
),
1620 DEBUGFS_REG32(DC_WIN_HP_FETCH_CONTROL
),
1621 DEBUGFS_REG32(DC_WINBUF_START_ADDR
),
1622 DEBUGFS_REG32(DC_WINBUF_START_ADDR_NS
),
1623 DEBUGFS_REG32(DC_WINBUF_START_ADDR_U
),
1624 DEBUGFS_REG32(DC_WINBUF_START_ADDR_U_NS
),
1625 DEBUGFS_REG32(DC_WINBUF_START_ADDR_V
),
1626 DEBUGFS_REG32(DC_WINBUF_START_ADDR_V_NS
),
1627 DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET
),
1628 DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET_NS
),
1629 DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET
),
1630 DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET_NS
),
1631 DEBUGFS_REG32(DC_WINBUF_UFLOW_STATUS
),
1632 DEBUGFS_REG32(DC_WINBUF_AD_UFLOW_STATUS
),
1633 DEBUGFS_REG32(DC_WINBUF_BD_UFLOW_STATUS
),
1634 DEBUGFS_REG32(DC_WINBUF_CD_UFLOW_STATUS
),
1637 static int tegra_dc_show_regs(struct seq_file
*s
, void *data
)
1639 struct drm_info_node
*node
= s
->private;
1640 struct tegra_dc
*dc
= node
->info_ent
->data
;
1644 drm_modeset_lock(&dc
->base
.mutex
, NULL
);
1646 if (!dc
->base
.state
->active
) {
1651 for (i
= 0; i
< ARRAY_SIZE(tegra_dc_regs
); i
++) {
1652 unsigned int offset
= tegra_dc_regs
[i
].offset
;
1654 seq_printf(s
, "%-40s %#05x %08x\n", tegra_dc_regs
[i
].name
,
1655 offset
, tegra_dc_readl(dc
, offset
));
1659 drm_modeset_unlock(&dc
->base
.mutex
);
1663 static int tegra_dc_show_crc(struct seq_file
*s
, void *data
)
1665 struct drm_info_node
*node
= s
->private;
1666 struct tegra_dc
*dc
= node
->info_ent
->data
;
1670 drm_modeset_lock(&dc
->base
.mutex
, NULL
);
1672 if (!dc
->base
.state
->active
) {
1677 value
= DC_COM_CRC_CONTROL_ACTIVE_DATA
| DC_COM_CRC_CONTROL_ENABLE
;
1678 tegra_dc_writel(dc
, value
, DC_COM_CRC_CONTROL
);
1679 tegra_dc_commit(dc
);
1681 drm_crtc_wait_one_vblank(&dc
->base
);
1682 drm_crtc_wait_one_vblank(&dc
->base
);
1684 value
= tegra_dc_readl(dc
, DC_COM_CRC_CHECKSUM
);
1685 seq_printf(s
, "%08x\n", value
);
1687 tegra_dc_writel(dc
, 0, DC_COM_CRC_CONTROL
);
1690 drm_modeset_unlock(&dc
->base
.mutex
);
1694 static int tegra_dc_show_stats(struct seq_file
*s
, void *data
)
1696 struct drm_info_node
*node
= s
->private;
1697 struct tegra_dc
*dc
= node
->info_ent
->data
;
1699 seq_printf(s
, "frames: %lu\n", dc
->stats
.frames
);
1700 seq_printf(s
, "vblank: %lu\n", dc
->stats
.vblank
);
1701 seq_printf(s
, "underflow: %lu\n", dc
->stats
.underflow
);
1702 seq_printf(s
, "overflow: %lu\n", dc
->stats
.overflow
);
1704 seq_printf(s
, "frames total: %lu\n", dc
->stats
.frames_total
);
1705 seq_printf(s
, "vblank total: %lu\n", dc
->stats
.vblank_total
);
1706 seq_printf(s
, "underflow total: %lu\n", dc
->stats
.underflow_total
);
1707 seq_printf(s
, "overflow total: %lu\n", dc
->stats
.overflow_total
);
1712 static struct drm_info_list debugfs_files
[] = {
1713 { "regs", tegra_dc_show_regs
, 0, NULL
},
1714 { "crc", tegra_dc_show_crc
, 0, NULL
},
1715 { "stats", tegra_dc_show_stats
, 0, NULL
},
1718 static int tegra_dc_late_register(struct drm_crtc
*crtc
)
1720 unsigned int i
, count
= ARRAY_SIZE(debugfs_files
);
1721 struct drm_minor
*minor
= crtc
->dev
->primary
;
1722 struct dentry
*root
;
1723 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
1725 #ifdef CONFIG_DEBUG_FS
1726 root
= crtc
->debugfs_entry
;
1731 dc
->debugfs_files
= kmemdup(debugfs_files
, sizeof(debugfs_files
),
1733 if (!dc
->debugfs_files
)
1736 for (i
= 0; i
< count
; i
++)
1737 dc
->debugfs_files
[i
].data
= dc
;
1739 drm_debugfs_create_files(dc
->debugfs_files
, count
, root
, minor
);
1744 static void tegra_dc_early_unregister(struct drm_crtc
*crtc
)
1746 unsigned int count
= ARRAY_SIZE(debugfs_files
);
1747 struct drm_minor
*minor
= crtc
->dev
->primary
;
1748 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
1749 struct dentry
*root
;
1751 #ifdef CONFIG_DEBUG_FS
1752 root
= crtc
->debugfs_entry
;
1757 drm_debugfs_remove_files(dc
->debugfs_files
, count
, root
, minor
);
1758 kfree(dc
->debugfs_files
);
1759 dc
->debugfs_files
= NULL
;
1762 static u32
tegra_dc_get_vblank_counter(struct drm_crtc
*crtc
)
1764 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
1766 /* XXX vblank syncpoints don't work with nvdisplay yet */
1767 if (dc
->syncpt
&& !dc
->soc
->has_nvdisplay
)
1768 return host1x_syncpt_read(dc
->syncpt
);
1770 /* fallback to software emulated VBLANK counter */
1771 return (u32
)drm_crtc_vblank_count(&dc
->base
);
1774 static int tegra_dc_enable_vblank(struct drm_crtc
*crtc
)
1776 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
1779 value
= tegra_dc_readl(dc
, DC_CMD_INT_MASK
);
1780 value
|= VBLANK_INT
;
1781 tegra_dc_writel(dc
, value
, DC_CMD_INT_MASK
);
1786 static void tegra_dc_disable_vblank(struct drm_crtc
*crtc
)
1788 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
1791 value
= tegra_dc_readl(dc
, DC_CMD_INT_MASK
);
1792 value
&= ~VBLANK_INT
;
1793 tegra_dc_writel(dc
, value
, DC_CMD_INT_MASK
);
1796 static const struct drm_crtc_funcs tegra_crtc_funcs
= {
1797 .page_flip
= drm_atomic_helper_page_flip
,
1798 .set_config
= drm_atomic_helper_set_config
,
1799 .destroy
= tegra_dc_destroy
,
1800 .reset
= tegra_crtc_reset
,
1801 .atomic_duplicate_state
= tegra_crtc_atomic_duplicate_state
,
1802 .atomic_destroy_state
= tegra_crtc_atomic_destroy_state
,
1803 .late_register
= tegra_dc_late_register
,
1804 .early_unregister
= tegra_dc_early_unregister
,
1805 .get_vblank_counter
= tegra_dc_get_vblank_counter
,
1806 .enable_vblank
= tegra_dc_enable_vblank
,
1807 .disable_vblank
= tegra_dc_disable_vblank
,
1810 static int tegra_dc_set_timings(struct tegra_dc
*dc
,
1811 struct drm_display_mode
*mode
)
1813 unsigned int h_ref_to_sync
= 1;
1814 unsigned int v_ref_to_sync
= 1;
1815 unsigned long value
;
1817 if (!dc
->soc
->has_nvdisplay
) {
1818 tegra_dc_writel(dc
, 0x0, DC_DISP_DISP_TIMING_OPTIONS
);
1820 value
= (v_ref_to_sync
<< 16) | h_ref_to_sync
;
1821 tegra_dc_writel(dc
, value
, DC_DISP_REF_TO_SYNC
);
1824 value
= ((mode
->vsync_end
- mode
->vsync_start
) << 16) |
1825 ((mode
->hsync_end
- mode
->hsync_start
) << 0);
1826 tegra_dc_writel(dc
, value
, DC_DISP_SYNC_WIDTH
);
1828 value
= ((mode
->vtotal
- mode
->vsync_end
) << 16) |
1829 ((mode
->htotal
- mode
->hsync_end
) << 0);
1830 tegra_dc_writel(dc
, value
, DC_DISP_BACK_PORCH
);
1832 value
= ((mode
->vsync_start
- mode
->vdisplay
) << 16) |
1833 ((mode
->hsync_start
- mode
->hdisplay
) << 0);
1834 tegra_dc_writel(dc
, value
, DC_DISP_FRONT_PORCH
);
1836 value
= (mode
->vdisplay
<< 16) | mode
->hdisplay
;
1837 tegra_dc_writel(dc
, value
, DC_DISP_ACTIVE
);
1843 * tegra_dc_state_setup_clock - check clock settings and store them in atomic
1845 * @dc: display controller
1846 * @crtc_state: CRTC atomic state
1847 * @clk: parent clock for display controller
1848 * @pclk: pixel clock
1849 * @div: shift clock divider
1852 * 0 on success or a negative error-code on failure.
1854 int tegra_dc_state_setup_clock(struct tegra_dc
*dc
,
1855 struct drm_crtc_state
*crtc_state
,
1856 struct clk
*clk
, unsigned long pclk
,
1859 struct tegra_dc_state
*state
= to_dc_state(crtc_state
);
1861 if (!clk_has_parent(dc
->clk
, clk
))
1871 static void tegra_dc_update_voltage_state(struct tegra_dc
*dc
,
1872 struct tegra_dc_state
*state
)
1874 unsigned long rate
, pstate
;
1875 struct dev_pm_opp
*opp
;
1878 if (!dc
->has_opp_table
)
1881 /* calculate actual pixel clock rate which depends on internal divider */
1882 rate
= DIV_ROUND_UP(clk_get_rate(dc
->clk
) * 2, state
->div
+ 2);
1884 /* find suitable OPP for the rate */
1885 opp
= dev_pm_opp_find_freq_ceil(dc
->dev
, &rate
);
1888 * Very high resolution modes may results in a clock rate that is
1889 * above the characterized maximum. In this case it's okay to fall
1890 * back to the characterized maximum.
1892 if (opp
== ERR_PTR(-ERANGE
))
1893 opp
= dev_pm_opp_find_freq_floor(dc
->dev
, &rate
);
1896 dev_err(dc
->dev
, "failed to find OPP for %luHz: %pe\n",
1901 pstate
= dev_pm_opp_get_required_pstate(opp
, 0);
1902 dev_pm_opp_put(opp
);
1905 * The minimum core voltage depends on the pixel clock rate (which
1906 * depends on internal clock divider of the CRTC) and not on the
1907 * rate of the display controller clock. This is why we're not using
1908 * dev_pm_opp_set_rate() API and instead controlling the power domain
1911 err
= dev_pm_genpd_set_performance_state(dc
->dev
, pstate
);
1913 dev_err(dc
->dev
, "failed to set power domain state to %lu: %d\n",
1917 static void tegra_dc_set_clock_rate(struct tegra_dc
*dc
,
1918 struct tegra_dc_state
*state
)
1922 err
= clk_set_parent(dc
->clk
, state
->clk
);
1924 dev_err(dc
->dev
, "failed to set parent clock: %d\n", err
);
1927 * Outputs may not want to change the parent clock rate. This is only
1928 * relevant to Tegra20 where only a single display PLL is available.
1929 * Since that PLL would typically be used for HDMI, an internal LVDS
1930 * panel would need to be driven by some other clock such as PLL_P
1931 * which is shared with other peripherals. Changing the clock rate
1932 * should therefore be avoided.
1934 if (state
->pclk
> 0) {
1935 err
= clk_set_rate(state
->clk
, state
->pclk
);
1938 "failed to set clock rate to %lu Hz\n",
1941 err
= clk_set_rate(dc
->clk
, state
->pclk
);
1943 dev_err(dc
->dev
, "failed to set clock %pC to %lu Hz: %d\n",
1944 dc
->clk
, state
->pclk
, err
);
1947 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc
->clk
),
1949 DRM_DEBUG_KMS("pclk: %lu\n", state
->pclk
);
1951 tegra_dc_update_voltage_state(dc
, state
);
1954 static void tegra_dc_stop(struct tegra_dc
*dc
)
1958 /* stop the display controller */
1959 value
= tegra_dc_readl(dc
, DC_CMD_DISPLAY_COMMAND
);
1960 value
&= ~DISP_CTRL_MODE_MASK
;
1961 tegra_dc_writel(dc
, value
, DC_CMD_DISPLAY_COMMAND
);
1963 tegra_dc_commit(dc
);
1966 static bool tegra_dc_idle(struct tegra_dc
*dc
)
1970 value
= tegra_dc_readl_active(dc
, DC_CMD_DISPLAY_COMMAND
);
1972 return (value
& DISP_CTRL_MODE_MASK
) == 0;
1975 static int tegra_dc_wait_idle(struct tegra_dc
*dc
, unsigned long timeout
)
1977 timeout
= jiffies
+ msecs_to_jiffies(timeout
);
1979 while (time_before(jiffies
, timeout
)) {
1980 if (tegra_dc_idle(dc
))
1983 usleep_range(1000, 2000);
1986 dev_dbg(dc
->dev
, "timeout waiting for DC to become idle\n");
1991 tegra_crtc_update_memory_bandwidth(struct drm_crtc
*crtc
,
1992 struct drm_atomic_state
*state
,
1993 bool prepare_bandwidth_transition
)
1995 const struct tegra_plane_state
*old_tegra_state
, *new_tegra_state
;
1996 u32 i
, new_avg_bw
, old_avg_bw
, new_peak_bw
, old_peak_bw
;
1997 const struct drm_plane_state
*old_plane_state
;
1998 const struct drm_crtc_state
*old_crtc_state
;
1999 struct tegra_dc_window window
, old_window
;
2000 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
2001 struct tegra_plane
*tegra
;
2002 struct drm_plane
*plane
;
2004 if (dc
->soc
->has_nvdisplay
)
2007 old_crtc_state
= drm_atomic_get_old_crtc_state(state
, crtc
);
2009 if (!crtc
->state
->active
) {
2010 if (!old_crtc_state
->active
)
2014 * When CRTC is disabled on DPMS, the state of attached planes
2015 * is kept unchanged. Hence we need to enforce removal of the
2016 * bandwidths from the ICC paths.
2018 drm_atomic_crtc_for_each_plane(plane
, crtc
) {
2019 tegra
= to_tegra_plane(plane
);
2021 icc_set_bw(tegra
->icc_mem
, 0, 0);
2022 icc_set_bw(tegra
->icc_mem_vfilter
, 0, 0);
2028 for_each_old_plane_in_state(old_crtc_state
->state
, plane
,
2029 old_plane_state
, i
) {
2030 old_tegra_state
= to_const_tegra_plane_state(old_plane_state
);
2031 new_tegra_state
= to_const_tegra_plane_state(plane
->state
);
2032 tegra
= to_tegra_plane(plane
);
2035 * We're iterating over the global atomic state and it contains
2036 * planes from another CRTC, hence we need to filter out the
2037 * planes unrelated to this CRTC.
2039 if (tegra
->dc
!= dc
)
2042 new_avg_bw
= new_tegra_state
->avg_memory_bandwidth
;
2043 old_avg_bw
= old_tegra_state
->avg_memory_bandwidth
;
2045 new_peak_bw
= new_tegra_state
->total_peak_memory_bandwidth
;
2046 old_peak_bw
= old_tegra_state
->total_peak_memory_bandwidth
;
2049 * See the comment related to !crtc->state->active above,
2050 * which explains why bandwidths need to be updated when
2051 * CRTC is turning ON.
2053 if (new_avg_bw
== old_avg_bw
&& new_peak_bw
== old_peak_bw
&&
2054 old_crtc_state
->active
)
2057 window
.src
.h
= drm_rect_height(&plane
->state
->src
) >> 16;
2058 window
.dst
.h
= drm_rect_height(&plane
->state
->dst
);
2060 old_window
.src
.h
= drm_rect_height(&old_plane_state
->src
) >> 16;
2061 old_window
.dst
.h
= drm_rect_height(&old_plane_state
->dst
);
2064 * During the preparation phase (atomic_begin), the memory
2065 * freq should go high before the DC changes are committed
2066 * if bandwidth requirement goes up, otherwise memory freq
2067 * should to stay high if BW requirement goes down. The
2068 * opposite applies to the completion phase (post_commit).
2070 if (prepare_bandwidth_transition
) {
2071 new_avg_bw
= max(old_avg_bw
, new_avg_bw
);
2072 new_peak_bw
= max(old_peak_bw
, new_peak_bw
);
2074 if (tegra_plane_use_vertical_filtering(tegra
, &old_window
))
2075 window
= old_window
;
2078 icc_set_bw(tegra
->icc_mem
, new_avg_bw
, new_peak_bw
);
2080 if (tegra_plane_use_vertical_filtering(tegra
, &window
))
2081 icc_set_bw(tegra
->icc_mem_vfilter
, new_avg_bw
, new_peak_bw
);
2083 icc_set_bw(tegra
->icc_mem_vfilter
, 0, 0);
2087 static void tegra_crtc_atomic_disable(struct drm_crtc
*crtc
,
2088 struct drm_atomic_state
*state
)
2090 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
2094 if (!tegra_dc_idle(dc
)) {
2098 * Ignore the return value, there isn't anything useful to do
2099 * in case this fails.
2101 tegra_dc_wait_idle(dc
, 100);
2105 * This should really be part of the RGB encoder driver, but clearing
2106 * these bits has the side-effect of stopping the display controller.
2107 * When that happens no VBLANK interrupts will be raised. At the same
2108 * time the encoder is disabled before the display controller, so the
2109 * above code is always going to timeout waiting for the controller
2112 * Given the close coupling between the RGB encoder and the display
2113 * controller doing it here is still kind of okay. None of the other
2114 * encoder drivers require these bits to be cleared.
2116 * XXX: Perhaps given that the display controller is switched off at
2117 * this point anyway maybe clearing these bits isn't even useful for
2121 value
= tegra_dc_readl(dc
, DC_CMD_DISPLAY_POWER_CONTROL
);
2122 value
&= ~(PW0_ENABLE
| PW1_ENABLE
| PW2_ENABLE
| PW3_ENABLE
|
2123 PW4_ENABLE
| PM0_ENABLE
| PM1_ENABLE
);
2124 tegra_dc_writel(dc
, value
, DC_CMD_DISPLAY_POWER_CONTROL
);
2127 tegra_dc_stats_reset(&dc
->stats
);
2128 drm_crtc_vblank_off(crtc
);
2130 spin_lock_irq(&crtc
->dev
->event_lock
);
2132 if (crtc
->state
->event
) {
2133 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
2134 crtc
->state
->event
= NULL
;
2137 spin_unlock_irq(&crtc
->dev
->event_lock
);
2139 err
= host1x_client_suspend(&dc
->client
);
2141 dev_err(dc
->dev
, "failed to suspend: %d\n", err
);
2143 if (dc
->has_opp_table
) {
2144 err
= dev_pm_genpd_set_performance_state(dc
->dev
, 0);
2147 "failed to clear power domain state: %d\n", err
);
2151 static void tegra_crtc_atomic_enable(struct drm_crtc
*crtc
,
2152 struct drm_atomic_state
*state
)
2154 struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
2155 struct tegra_dc_state
*crtc_state
= to_dc_state(crtc
->state
);
2156 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
2160 /* apply PLL changes */
2161 tegra_dc_set_clock_rate(dc
, crtc_state
);
2163 err
= host1x_client_resume(&dc
->client
);
2165 dev_err(dc
->dev
, "failed to resume: %d\n", err
);
2169 /* initialize display controller */
2171 u32 syncpt
= host1x_syncpt_id(dc
->syncpt
), enable
;
2173 if (dc
->soc
->has_nvdisplay
)
2178 value
= SYNCPT_CNTRL_NO_STALL
;
2179 tegra_dc_writel(dc
, value
, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL
);
2181 value
= enable
| syncpt
;
2182 tegra_dc_writel(dc
, value
, DC_CMD_CONT_SYNCPT_VSYNC
);
2185 if (dc
->soc
->has_nvdisplay
) {
2186 value
= DSC_TO_UF_INT
| DSC_BBUF_UF_INT
| DSC_RBUF_UF_INT
|
2188 tegra_dc_writel(dc
, value
, DC_CMD_INT_TYPE
);
2190 value
= DSC_TO_UF_INT
| DSC_BBUF_UF_INT
| DSC_RBUF_UF_INT
|
2191 DSC_OBUF_UF_INT
| SD3_BUCKET_WALK_DONE_INT
|
2192 HEAD_UF_INT
| MSF_INT
| REG_TMOUT_INT
|
2193 REGION_CRC_INT
| V_PULSE2_INT
| V_PULSE3_INT
|
2194 VBLANK_INT
| FRAME_END_INT
;
2195 tegra_dc_writel(dc
, value
, DC_CMD_INT_POLARITY
);
2197 value
= SD3_BUCKET_WALK_DONE_INT
| HEAD_UF_INT
| VBLANK_INT
|
2199 tegra_dc_writel(dc
, value
, DC_CMD_INT_ENABLE
);
2201 value
= HEAD_UF_INT
| REG_TMOUT_INT
| FRAME_END_INT
;
2202 tegra_dc_writel(dc
, value
, DC_CMD_INT_MASK
);
2204 tegra_dc_writel(dc
, READ_MUX
, DC_CMD_STATE_ACCESS
);
2206 value
= WIN_A_UF_INT
| WIN_B_UF_INT
| WIN_C_UF_INT
|
2207 WIN_A_OF_INT
| WIN_B_OF_INT
| WIN_C_OF_INT
;
2208 tegra_dc_writel(dc
, value
, DC_CMD_INT_TYPE
);
2210 value
= WIN_A_UF_INT
| WIN_B_UF_INT
| WIN_C_UF_INT
|
2211 WIN_A_OF_INT
| WIN_B_OF_INT
| WIN_C_OF_INT
;
2212 tegra_dc_writel(dc
, value
, DC_CMD_INT_POLARITY
);
2214 /* initialize timer */
2215 value
= CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
2216 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
2217 tegra_dc_writel(dc
, value
, DC_DISP_DISP_MEM_HIGH_PRIORITY
);
2219 value
= CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
2220 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
2221 tegra_dc_writel(dc
, value
, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER
);
2223 value
= VBLANK_INT
| WIN_A_UF_INT
| WIN_B_UF_INT
| WIN_C_UF_INT
|
2224 WIN_A_OF_INT
| WIN_B_OF_INT
| WIN_C_OF_INT
;
2225 tegra_dc_writel(dc
, value
, DC_CMD_INT_ENABLE
);
2227 value
= WIN_A_UF_INT
| WIN_B_UF_INT
| WIN_C_UF_INT
|
2228 WIN_A_OF_INT
| WIN_B_OF_INT
| WIN_C_OF_INT
;
2229 tegra_dc_writel(dc
, value
, DC_CMD_INT_MASK
);
2232 if (dc
->soc
->supports_background_color
)
2233 tegra_dc_writel(dc
, 0, DC_DISP_BLEND_BACKGROUND_COLOR
);
2235 tegra_dc_writel(dc
, 0, DC_DISP_BORDER_COLOR
);
2237 /* apply pixel clock changes */
2238 if (!dc
->soc
->has_nvdisplay
) {
2239 value
= SHIFT_CLK_DIVIDER(crtc_state
->div
) | PIXEL_CLK_DIVIDER_PCD1
;
2240 tegra_dc_writel(dc
, value
, DC_DISP_DISP_CLOCK_CONTROL
);
2243 /* program display mode */
2244 tegra_dc_set_timings(dc
, mode
);
2246 /* interlacing isn't supported yet, so disable it */
2247 if (dc
->soc
->supports_interlacing
) {
2248 value
= tegra_dc_readl(dc
, DC_DISP_INTERLACE_CONTROL
);
2249 value
&= ~INTERLACE_ENABLE
;
2250 tegra_dc_writel(dc
, value
, DC_DISP_INTERLACE_CONTROL
);
2253 value
= tegra_dc_readl(dc
, DC_CMD_DISPLAY_COMMAND
);
2254 value
&= ~DISP_CTRL_MODE_MASK
;
2255 value
|= DISP_CTRL_MODE_C_DISPLAY
;
2256 tegra_dc_writel(dc
, value
, DC_CMD_DISPLAY_COMMAND
);
2258 if (!dc
->soc
->has_nvdisplay
) {
2259 value
= tegra_dc_readl(dc
, DC_CMD_DISPLAY_POWER_CONTROL
);
2260 value
|= PW0_ENABLE
| PW1_ENABLE
| PW2_ENABLE
| PW3_ENABLE
|
2261 PW4_ENABLE
| PM0_ENABLE
| PM1_ENABLE
;
2262 tegra_dc_writel(dc
, value
, DC_CMD_DISPLAY_POWER_CONTROL
);
2265 /* enable underflow reporting and display red for missing pixels */
2266 if (dc
->soc
->has_nvdisplay
) {
2267 value
= UNDERFLOW_MODE_RED
| UNDERFLOW_REPORT_ENABLE
;
2268 tegra_dc_writel(dc
, value
, DC_COM_RG_UNDERFLOW
);
2272 /* XXX: parameterize? */
2273 value
= SC0_H_QUALIFIER_NONE
| SC1_H_QUALIFIER_NONE
;
2274 tegra_dc_writel(dc
, value
, DC_DISP_SHIFT_CLOCK_OPTIONS
);
2277 tegra_dc_commit(dc
);
2279 drm_crtc_vblank_on(crtc
);
2282 static void tegra_crtc_atomic_begin(struct drm_crtc
*crtc
,
2283 struct drm_atomic_state
*state
)
2285 unsigned long flags
;
2287 tegra_crtc_update_memory_bandwidth(crtc
, state
, true);
2289 if (crtc
->state
->event
) {
2290 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
2292 if (drm_crtc_vblank_get(crtc
) != 0)
2293 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
2295 drm_crtc_arm_vblank_event(crtc
, crtc
->state
->event
);
2297 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
2299 crtc
->state
->event
= NULL
;
2303 static void tegra_crtc_atomic_flush(struct drm_crtc
*crtc
,
2304 struct drm_atomic_state
*state
)
2306 struct drm_crtc_state
*crtc_state
= drm_atomic_get_new_crtc_state(state
,
2308 struct tegra_dc_state
*dc_state
= to_dc_state(crtc_state
);
2309 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
2312 value
= dc_state
->planes
<< 8 | GENERAL_UPDATE
;
2313 tegra_dc_writel(dc
, value
, DC_CMD_STATE_CONTROL
);
2314 value
= tegra_dc_readl(dc
, DC_CMD_STATE_CONTROL
);
2316 value
= dc_state
->planes
| GENERAL_ACT_REQ
;
2317 tegra_dc_writel(dc
, value
, DC_CMD_STATE_CONTROL
);
2318 value
= tegra_dc_readl(dc
, DC_CMD_STATE_CONTROL
);
2321 static bool tegra_plane_is_cursor(const struct drm_plane_state
*state
)
2323 const struct tegra_dc_soc_info
*soc
= to_tegra_dc(state
->crtc
)->soc
;
2324 const struct drm_format_info
*fmt
= state
->fb
->format
;
2325 unsigned int src_w
= drm_rect_width(&state
->src
) >> 16;
2326 unsigned int dst_w
= drm_rect_width(&state
->dst
);
2328 if (state
->plane
->type
!= DRM_PLANE_TYPE_CURSOR
)
2331 if (soc
->supports_cursor
)
2334 if (src_w
!= dst_w
|| fmt
->num_planes
!= 1 || src_w
* fmt
->cpp
[0] > 256)
2340 static unsigned long
2341 tegra_plane_overlap_mask(struct drm_crtc_state
*state
,
2342 const struct drm_plane_state
*plane_state
)
2344 const struct drm_plane_state
*other_state
;
2345 const struct tegra_plane
*tegra
;
2346 unsigned long overlap_mask
= 0;
2347 struct drm_plane
*plane
;
2348 struct drm_rect rect
;
2350 if (!plane_state
->visible
|| !plane_state
->fb
)
2354 * Data-prefetch FIFO will easily help to overcome temporal memory
2355 * pressure if other plane overlaps with the cursor plane.
2357 if (tegra_plane_is_cursor(plane_state
))
2360 drm_atomic_crtc_state_for_each_plane_state(plane
, other_state
, state
) {
2361 rect
= plane_state
->dst
;
2363 tegra
= to_tegra_plane(other_state
->plane
);
2365 if (!other_state
->visible
|| !other_state
->fb
)
2369 * Ignore cursor plane overlaps because it's not practical to
2370 * assume that it contributes to the bandwidth in overlapping
2371 * area if window width is small.
2373 if (tegra_plane_is_cursor(other_state
))
2376 if (drm_rect_intersect(&rect
, &other_state
->dst
))
2377 overlap_mask
|= BIT(tegra
->index
);
2380 return overlap_mask
;
2383 static int tegra_crtc_calculate_memory_bandwidth(struct drm_crtc
*crtc
,
2384 struct drm_atomic_state
*state
)
2386 ulong overlap_mask
[TEGRA_DC_LEGACY_PLANES_NUM
] = {}, mask
;
2387 u32 plane_peak_bw
[TEGRA_DC_LEGACY_PLANES_NUM
] = {};
2388 bool all_planes_overlap_simultaneously
= true;
2389 const struct tegra_plane_state
*tegra_state
;
2390 const struct drm_plane_state
*plane_state
;
2391 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
2392 struct drm_crtc_state
*new_state
;
2393 struct tegra_plane
*tegra
;
2394 struct drm_plane
*plane
;
2397 * The nv-display uses shared planes. The algorithm below assumes
2398 * maximum 3 planes per-CRTC, this assumption isn't applicable to
2399 * the nv-display. Note that T124 support has additional windows,
2400 * but currently they aren't supported by the driver.
2402 if (dc
->soc
->has_nvdisplay
)
2405 new_state
= drm_atomic_get_new_crtc_state(state
, crtc
);
2408 * For overlapping planes pixel's data is fetched for each plane at
2409 * the same time, hence bandwidths are accumulated in this case.
2410 * This needs to be taken into account for calculating total bandwidth
2411 * consumed by all planes.
2413 * Here we get the overlapping state of each plane, which is a
2414 * bitmask of plane indices telling with what planes there is an
2415 * overlap. Note that bitmask[plane] includes BIT(plane) in order
2416 * to make further code nicer and simpler.
2418 drm_atomic_crtc_state_for_each_plane_state(plane
, plane_state
, new_state
) {
2419 tegra_state
= to_const_tegra_plane_state(plane_state
);
2420 tegra
= to_tegra_plane(plane
);
2422 if (WARN_ON_ONCE(tegra
->index
>= TEGRA_DC_LEGACY_PLANES_NUM
))
2425 plane_peak_bw
[tegra
->index
] = tegra_state
->peak_memory_bandwidth
;
2426 mask
= tegra_plane_overlap_mask(new_state
, plane_state
);
2427 overlap_mask
[tegra
->index
] = mask
;
2429 if (hweight_long(mask
) != 3)
2430 all_planes_overlap_simultaneously
= false;
2434 * Then we calculate maximum bandwidth of each plane state.
2435 * The bandwidth includes the plane BW + BW of the "simultaneously"
2436 * overlapping planes, where "simultaneously" means areas where DC
2437 * fetches from the planes simultaneously during of scan-out process.
2439 * For example, if plane A overlaps with planes B and C, but B and C
2440 * don't overlap, then the peak bandwidth will be either in area where
2441 * A-and-B or A-and-C planes overlap.
2443 * The plane_peak_bw[] contains peak memory bandwidth values of
2444 * each plane, this information is needed by interconnect provider
2445 * in order to set up latency allowance based on the peak BW, see
2446 * tegra_crtc_update_memory_bandwidth().
2448 drm_atomic_crtc_state_for_each_plane_state(plane
, plane_state
, new_state
) {
2449 u32 i
, old_peak_bw
, new_peak_bw
, overlap_bw
= 0;
2452 * Note that plane's atomic check doesn't touch the
2453 * total_peak_memory_bandwidth of enabled plane, hence the
2454 * current state contains the old bandwidth state from the
2455 * previous CRTC commit.
2457 tegra_state
= to_const_tegra_plane_state(plane_state
);
2458 tegra
= to_tegra_plane(plane
);
2460 for_each_set_bit(i
, &overlap_mask
[tegra
->index
], 3) {
2461 if (i
== tegra
->index
)
2464 if (all_planes_overlap_simultaneously
)
2465 overlap_bw
+= plane_peak_bw
[i
];
2467 overlap_bw
= max(overlap_bw
, plane_peak_bw
[i
]);
2470 new_peak_bw
= plane_peak_bw
[tegra
->index
] + overlap_bw
;
2471 old_peak_bw
= tegra_state
->total_peak_memory_bandwidth
;
2474 * If plane's peak bandwidth changed (for example plane isn't
2475 * overlapped anymore) and plane isn't in the atomic state,
2476 * then add plane to the state in order to have the bandwidth
2479 if (old_peak_bw
!= new_peak_bw
) {
2480 struct tegra_plane_state
*new_tegra_state
;
2481 struct drm_plane_state
*new_plane_state
;
2483 new_plane_state
= drm_atomic_get_plane_state(state
, plane
);
2484 if (IS_ERR(new_plane_state
))
2485 return PTR_ERR(new_plane_state
);
2487 new_tegra_state
= to_tegra_plane_state(new_plane_state
);
2488 new_tegra_state
->total_peak_memory_bandwidth
= new_peak_bw
;
2495 static int tegra_crtc_atomic_check(struct drm_crtc
*crtc
,
2496 struct drm_atomic_state
*state
)
2500 err
= tegra_crtc_calculate_memory_bandwidth(crtc
, state
);
2507 void tegra_crtc_atomic_post_commit(struct drm_crtc
*crtc
,
2508 struct drm_atomic_state
*state
)
2511 * Display bandwidth is allowed to go down only once hardware state
2512 * is known to be armed, i.e. state was committed and VBLANK event
2515 tegra_crtc_update_memory_bandwidth(crtc
, state
, false);
2518 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs
= {
2519 .atomic_check
= tegra_crtc_atomic_check
,
2520 .atomic_begin
= tegra_crtc_atomic_begin
,
2521 .atomic_flush
= tegra_crtc_atomic_flush
,
2522 .atomic_enable
= tegra_crtc_atomic_enable
,
2523 .atomic_disable
= tegra_crtc_atomic_disable
,
2526 static irqreturn_t
tegra_dc_irq(int irq
, void *data
)
2528 struct tegra_dc
*dc
= data
;
2529 unsigned long status
;
2531 status
= tegra_dc_readl(dc
, DC_CMD_INT_STATUS
);
2532 tegra_dc_writel(dc
, status
, DC_CMD_INT_STATUS
);
2534 if (status
& FRAME_END_INT
) {
2536 dev_dbg(dc->dev, "%s(): frame end\n", __func__);
2538 dc
->stats
.frames_total
++;
2542 if (status
& VBLANK_INT
) {
2544 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
2546 drm_crtc_handle_vblank(&dc
->base
);
2547 dc
->stats
.vblank_total
++;
2551 if (status
& (WIN_A_UF_INT
| WIN_B_UF_INT
| WIN_C_UF_INT
)) {
2553 dev_dbg(dc->dev, "%s(): underflow\n", __func__);
2555 dc
->stats
.underflow_total
++;
2556 dc
->stats
.underflow
++;
2559 if (status
& (WIN_A_OF_INT
| WIN_B_OF_INT
| WIN_C_OF_INT
)) {
2561 dev_dbg(dc->dev, "%s(): overflow\n", __func__);
2563 dc
->stats
.overflow_total
++;
2564 dc
->stats
.overflow
++;
2567 if (status
& HEAD_UF_INT
) {
2568 dev_dbg_ratelimited(dc
->dev
, "%s(): head underflow\n", __func__
);
2569 dc
->stats
.underflow_total
++;
2570 dc
->stats
.underflow
++;
2576 static bool tegra_dc_has_window_groups(struct tegra_dc
*dc
)
2580 if (!dc
->soc
->wgrps
)
2583 for (i
= 0; i
< dc
->soc
->num_wgrps
; i
++) {
2584 const struct tegra_windowgroup_soc
*wgrp
= &dc
->soc
->wgrps
[i
];
2586 if (wgrp
->dc
== dc
->pipe
&& wgrp
->num_windows
> 0)
2593 static int tegra_dc_early_init(struct host1x_client
*client
)
2595 struct drm_device
*drm
= dev_get_drvdata(client
->host
);
2596 struct tegra_drm
*tegra
= drm
->dev_private
;
2603 static int tegra_dc_init(struct host1x_client
*client
)
2605 struct drm_device
*drm
= dev_get_drvdata(client
->host
);
2606 unsigned long flags
= HOST1X_SYNCPT_CLIENT_MANAGED
;
2607 struct tegra_dc
*dc
= host1x_client_to_dc(client
);
2608 struct tegra_drm
*tegra
= drm
->dev_private
;
2609 struct drm_plane
*primary
= NULL
;
2610 struct drm_plane
*cursor
= NULL
;
2614 * DC has been reset by now, so VBLANK syncpoint can be released
2617 host1x_syncpt_release_vblank_reservation(client
, 26 + dc
->pipe
);
2620 * XXX do not register DCs with no window groups because we cannot
2621 * assign a primary plane to them, which in turn will cause KMS to
2624 if (!tegra_dc_has_window_groups(dc
))
2628 * Set the display hub as the host1x client parent for the display
2629 * controller. This is needed for the runtime reference counting that
2630 * ensures the display hub is always powered when any of the display
2633 if (dc
->soc
->has_nvdisplay
)
2634 client
->parent
= &tegra
->hub
->client
;
2636 dc
->syncpt
= host1x_syncpt_request(client
, flags
);
2638 dev_warn(dc
->dev
, "failed to allocate syncpoint\n");
2640 err
= host1x_client_iommu_attach(client
);
2641 if (err
< 0 && err
!= -ENODEV
) {
2642 dev_err(client
->dev
, "failed to attach to domain: %d\n", err
);
2647 primary
= tegra_dc_add_shared_planes(drm
, dc
);
2649 primary
= tegra_dc_add_planes(drm
, dc
);
2651 if (IS_ERR(primary
)) {
2652 err
= PTR_ERR(primary
);
2656 if (dc
->soc
->supports_cursor
) {
2657 cursor
= tegra_dc_cursor_plane_create(drm
, dc
);
2658 if (IS_ERR(cursor
)) {
2659 err
= PTR_ERR(cursor
);
2663 /* dedicate one overlay to mouse cursor */
2664 cursor
= tegra_dc_overlay_plane_create(drm
, dc
, 2, true);
2665 if (IS_ERR(cursor
)) {
2666 err
= PTR_ERR(cursor
);
2671 err
= drm_crtc_init_with_planes(drm
, &dc
->base
, primary
, cursor
,
2672 &tegra_crtc_funcs
, NULL
);
2676 drm_crtc_helper_add(&dc
->base
, &tegra_crtc_helper_funcs
);
2679 * Keep track of the minimum pitch alignment across all display
2682 if (dc
->soc
->pitch_align
> tegra
->pitch_align
)
2683 tegra
->pitch_align
= dc
->soc
->pitch_align
;
2685 /* track maximum resolution */
2686 if (dc
->soc
->has_nvdisplay
)
2687 drm
->mode_config
.max_width
= drm
->mode_config
.max_height
= 16384;
2689 drm
->mode_config
.max_width
= drm
->mode_config
.max_height
= 4096;
2691 err
= tegra_dc_rgb_init(drm
, dc
);
2692 if (err
< 0 && err
!= -ENODEV
) {
2693 dev_err(dc
->dev
, "failed to initialize RGB output: %d\n", err
);
2697 err
= devm_request_irq(dc
->dev
, dc
->irq
, tegra_dc_irq
, 0,
2698 dev_name(dc
->dev
), dc
);
2700 dev_err(dc
->dev
, "failed to request IRQ#%u: %d\n", dc
->irq
,
2706 * Inherit the DMA parameters (such as maximum segment size) from the
2707 * parent host1x device.
2709 client
->dev
->dma_parms
= client
->host
->dma_parms
;
2714 if (!IS_ERR_OR_NULL(cursor
))
2715 drm_plane_cleanup(cursor
);
2717 if (!IS_ERR(primary
))
2718 drm_plane_cleanup(primary
);
2720 host1x_client_iommu_detach(client
);
2721 host1x_syncpt_put(dc
->syncpt
);
2726 static int tegra_dc_exit(struct host1x_client
*client
)
2728 struct tegra_dc
*dc
= host1x_client_to_dc(client
);
2731 if (!tegra_dc_has_window_groups(dc
))
2734 /* avoid a dangling pointer just in case this disappears */
2735 client
->dev
->dma_parms
= NULL
;
2737 devm_free_irq(dc
->dev
, dc
->irq
, dc
);
2739 err
= tegra_dc_rgb_exit(dc
);
2741 dev_err(dc
->dev
, "failed to shutdown RGB output: %d\n", err
);
2745 host1x_client_iommu_detach(client
);
2746 host1x_syncpt_put(dc
->syncpt
);
2751 static int tegra_dc_late_exit(struct host1x_client
*client
)
2753 struct drm_device
*drm
= dev_get_drvdata(client
->host
);
2754 struct tegra_drm
*tegra
= drm
->dev_private
;
2761 static int tegra_dc_runtime_suspend(struct host1x_client
*client
)
2763 struct tegra_dc
*dc
= host1x_client_to_dc(client
);
2764 struct device
*dev
= client
->dev
;
2767 err
= reset_control_assert(dc
->rst
);
2769 dev_err(dev
, "failed to assert reset: %d\n", err
);
2773 if (dc
->soc
->has_powergate
)
2774 tegra_powergate_power_off(dc
->powergate
);
2776 clk_disable_unprepare(dc
->clk
);
2777 pm_runtime_put_sync(dev
);
2782 static int tegra_dc_runtime_resume(struct host1x_client
*client
)
2784 struct tegra_dc
*dc
= host1x_client_to_dc(client
);
2785 struct device
*dev
= client
->dev
;
2788 err
= pm_runtime_resume_and_get(dev
);
2790 dev_err(dev
, "failed to get runtime PM: %d\n", err
);
2794 if (dc
->soc
->has_powergate
) {
2795 err
= tegra_powergate_sequence_power_up(dc
->powergate
, dc
->clk
,
2798 dev_err(dev
, "failed to power partition: %d\n", err
);
2802 err
= clk_prepare_enable(dc
->clk
);
2804 dev_err(dev
, "failed to enable clock: %d\n", err
);
2808 err
= reset_control_deassert(dc
->rst
);
2810 dev_err(dev
, "failed to deassert reset: %d\n", err
);
2818 clk_disable_unprepare(dc
->clk
);
2820 pm_runtime_put_sync(dev
);
2824 static const struct host1x_client_ops dc_client_ops
= {
2825 .early_init
= tegra_dc_early_init
,
2826 .init
= tegra_dc_init
,
2827 .exit
= tegra_dc_exit
,
2828 .late_exit
= tegra_dc_late_exit
,
2829 .suspend
= tegra_dc_runtime_suspend
,
2830 .resume
= tegra_dc_runtime_resume
,
2833 static const struct tegra_dc_soc_info tegra20_dc_soc_info
= {
2834 .supports_background_color
= false,
2835 .supports_interlacing
= false,
2836 .supports_cursor
= false,
2837 .supports_block_linear
= false,
2838 .supports_sector_layout
= false,
2839 .has_legacy_blending
= true,
2841 .has_powergate
= false,
2843 .has_nvdisplay
= false,
2844 .num_primary_formats
= ARRAY_SIZE(tegra20_primary_formats
),
2845 .primary_formats
= tegra20_primary_formats
,
2846 .num_overlay_formats
= ARRAY_SIZE(tegra20_overlay_formats
),
2847 .overlay_formats
= tegra20_overlay_formats
,
2848 .modifiers
= tegra20_modifiers
,
2849 .has_win_a_without_filters
= true,
2850 .has_win_b_vfilter_mem_client
= true,
2851 .has_win_c_without_vert_filter
= true,
2852 .plane_tiled_memory_bandwidth_x2
= false,
2853 .has_pll_d2_out0
= false,
2856 static const struct tegra_dc_soc_info tegra30_dc_soc_info
= {
2857 .supports_background_color
= false,
2858 .supports_interlacing
= false,
2859 .supports_cursor
= false,
2860 .supports_block_linear
= false,
2861 .supports_sector_layout
= false,
2862 .has_legacy_blending
= true,
2864 .has_powergate
= false,
2865 .coupled_pm
= false,
2866 .has_nvdisplay
= false,
2867 .num_primary_formats
= ARRAY_SIZE(tegra20_primary_formats
),
2868 .primary_formats
= tegra20_primary_formats
,
2869 .num_overlay_formats
= ARRAY_SIZE(tegra20_overlay_formats
),
2870 .overlay_formats
= tegra20_overlay_formats
,
2871 .modifiers
= tegra20_modifiers
,
2872 .has_win_a_without_filters
= false,
2873 .has_win_b_vfilter_mem_client
= true,
2874 .has_win_c_without_vert_filter
= false,
2875 .plane_tiled_memory_bandwidth_x2
= true,
2876 .has_pll_d2_out0
= true,
2879 static const struct tegra_dc_soc_info tegra114_dc_soc_info
= {
2880 .supports_background_color
= false,
2881 .supports_interlacing
= false,
2882 .supports_cursor
= false,
2883 .supports_block_linear
= false,
2884 .supports_sector_layout
= false,
2885 .has_legacy_blending
= true,
2887 .has_powergate
= true,
2888 .coupled_pm
= false,
2889 .has_nvdisplay
= false,
2890 .num_primary_formats
= ARRAY_SIZE(tegra114_primary_formats
),
2891 .primary_formats
= tegra114_primary_formats
,
2892 .num_overlay_formats
= ARRAY_SIZE(tegra114_overlay_formats
),
2893 .overlay_formats
= tegra114_overlay_formats
,
2894 .modifiers
= tegra20_modifiers
,
2895 .has_win_a_without_filters
= false,
2896 .has_win_b_vfilter_mem_client
= false,
2897 .has_win_c_without_vert_filter
= false,
2898 .plane_tiled_memory_bandwidth_x2
= true,
2899 .has_pll_d2_out0
= true,
2902 static const struct tegra_dc_soc_info tegra124_dc_soc_info
= {
2903 .supports_background_color
= true,
2904 .supports_interlacing
= true,
2905 .supports_cursor
= true,
2906 .supports_block_linear
= true,
2907 .supports_sector_layout
= false,
2908 .has_legacy_blending
= false,
2910 .has_powergate
= true,
2911 .coupled_pm
= false,
2912 .has_nvdisplay
= false,
2913 .num_primary_formats
= ARRAY_SIZE(tegra124_primary_formats
),
2914 .primary_formats
= tegra124_primary_formats
,
2915 .num_overlay_formats
= ARRAY_SIZE(tegra124_overlay_formats
),
2916 .overlay_formats
= tegra124_overlay_formats
,
2917 .modifiers
= tegra124_modifiers
,
2918 .has_win_a_without_filters
= false,
2919 .has_win_b_vfilter_mem_client
= false,
2920 .has_win_c_without_vert_filter
= false,
2921 .plane_tiled_memory_bandwidth_x2
= false,
2922 .has_pll_d2_out0
= true,
2925 static const struct tegra_dc_soc_info tegra210_dc_soc_info
= {
2926 .supports_background_color
= true,
2927 .supports_interlacing
= true,
2928 .supports_cursor
= true,
2929 .supports_block_linear
= true,
2930 .supports_sector_layout
= false,
2931 .has_legacy_blending
= false,
2933 .has_powergate
= true,
2934 .coupled_pm
= false,
2935 .has_nvdisplay
= false,
2936 .num_primary_formats
= ARRAY_SIZE(tegra114_primary_formats
),
2937 .primary_formats
= tegra114_primary_formats
,
2938 .num_overlay_formats
= ARRAY_SIZE(tegra114_overlay_formats
),
2939 .overlay_formats
= tegra114_overlay_formats
,
2940 .modifiers
= tegra124_modifiers
,
2941 .has_win_a_without_filters
= false,
2942 .has_win_b_vfilter_mem_client
= false,
2943 .has_win_c_without_vert_filter
= false,
2944 .plane_tiled_memory_bandwidth_x2
= false,
2945 .has_pll_d2_out0
= true,
2948 static const struct tegra_windowgroup_soc tegra186_dc_wgrps
[] = {
2952 .windows
= (const unsigned int[]) { 0 },
2957 .windows
= (const unsigned int[]) { 1 },
2962 .windows
= (const unsigned int[]) { 2 },
2967 .windows
= (const unsigned int[]) { 3 },
2972 .windows
= (const unsigned int[]) { 4 },
2977 .windows
= (const unsigned int[]) { 5 },
2982 static const struct tegra_dc_soc_info tegra186_dc_soc_info
= {
2983 .supports_background_color
= true,
2984 .supports_interlacing
= true,
2985 .supports_cursor
= true,
2986 .supports_block_linear
= true,
2987 .supports_sector_layout
= false,
2988 .has_legacy_blending
= false,
2990 .has_powergate
= false,
2991 .coupled_pm
= false,
2992 .has_nvdisplay
= true,
2993 .wgrps
= tegra186_dc_wgrps
,
2994 .num_wgrps
= ARRAY_SIZE(tegra186_dc_wgrps
),
2995 .plane_tiled_memory_bandwidth_x2
= false,
2996 .has_pll_d2_out0
= false,
2999 static const struct tegra_windowgroup_soc tegra194_dc_wgrps
[] = {
3003 .windows
= (const unsigned int[]) { 0 },
3008 .windows
= (const unsigned int[]) { 1 },
3013 .windows
= (const unsigned int[]) { 2 },
3018 .windows
= (const unsigned int[]) { 3 },
3023 .windows
= (const unsigned int[]) { 4 },
3028 .windows
= (const unsigned int[]) { 5 },
3033 static const struct tegra_dc_soc_info tegra194_dc_soc_info
= {
3034 .supports_background_color
= true,
3035 .supports_interlacing
= true,
3036 .supports_cursor
= true,
3037 .supports_block_linear
= true,
3038 .supports_sector_layout
= true,
3039 .has_legacy_blending
= false,
3041 .has_powergate
= false,
3042 .coupled_pm
= false,
3043 .has_nvdisplay
= true,
3044 .wgrps
= tegra194_dc_wgrps
,
3045 .num_wgrps
= ARRAY_SIZE(tegra194_dc_wgrps
),
3046 .plane_tiled_memory_bandwidth_x2
= false,
3047 .has_pll_d2_out0
= false,
3050 static const struct of_device_id tegra_dc_of_match
[] = {
3052 .compatible
= "nvidia,tegra194-dc",
3053 .data
= &tegra194_dc_soc_info
,
3055 .compatible
= "nvidia,tegra186-dc",
3056 .data
= &tegra186_dc_soc_info
,
3058 .compatible
= "nvidia,tegra210-dc",
3059 .data
= &tegra210_dc_soc_info
,
3061 .compatible
= "nvidia,tegra124-dc",
3062 .data
= &tegra124_dc_soc_info
,
3064 .compatible
= "nvidia,tegra114-dc",
3065 .data
= &tegra114_dc_soc_info
,
3067 .compatible
= "nvidia,tegra30-dc",
3068 .data
= &tegra30_dc_soc_info
,
3070 .compatible
= "nvidia,tegra20-dc",
3071 .data
= &tegra20_dc_soc_info
,
3076 MODULE_DEVICE_TABLE(of
, tegra_dc_of_match
);
3078 static int tegra_dc_parse_dt(struct tegra_dc
*dc
)
3080 struct device_node
*np
;
3084 err
= of_property_read_u32(dc
->dev
->of_node
, "nvidia,head", &value
);
3086 dev_err(dc
->dev
, "missing \"nvidia,head\" property\n");
3089 * If the nvidia,head property isn't present, try to find the
3090 * correct head number by looking up the position of this
3091 * display controller's node within the device tree. Assuming
3092 * that the nodes are ordered properly in the DTS file and
3093 * that the translation into a flattened device tree blob
3094 * preserves that ordering this will actually yield the right
3097 * If those assumptions don't hold, this will still work for
3098 * cases where only a single display controller is used.
3100 for_each_matching_node(np
, tegra_dc_of_match
) {
3101 if (np
== dc
->dev
->of_node
) {
3115 static int tegra_dc_match_by_pipe(struct device
*dev
, const void *data
)
3117 struct tegra_dc
*dc
= dev_get_drvdata(dev
);
3118 unsigned int pipe
= (unsigned long)(void *)data
;
3120 return dc
->pipe
== pipe
;
3123 static int tegra_dc_couple(struct tegra_dc
*dc
)
3126 * On Tegra20, DC1 requires DC0 to be taken out of reset in order to
3127 * be enabled, otherwise CPU hangs on writing to CMD_DISPLAY_COMMAND /
3128 * POWER_CONTROL registers during CRTC enabling.
3130 if (dc
->soc
->coupled_pm
&& dc
->pipe
== 1) {
3131 struct device
*companion
;
3132 struct tegra_dc
*parent
;
3134 companion
= driver_find_device(dc
->dev
->driver
, NULL
, (const void *)0,
3135 tegra_dc_match_by_pipe
);
3137 return -EPROBE_DEFER
;
3139 parent
= dev_get_drvdata(companion
);
3140 dc
->client
.parent
= &parent
->client
;
3142 dev_dbg(dc
->dev
, "coupled to %s\n", dev_name(companion
));
3148 static int tegra_dc_init_opp_table(struct tegra_dc
*dc
)
3150 struct tegra_core_opp_params opp_params
= {};
3153 err
= devm_tegra_core_dev_init_opp_table(dc
->dev
, &opp_params
);
3154 if (err
&& err
!= -ENODEV
)
3158 dc
->has_opp_table
= false;
3160 dc
->has_opp_table
= true;
3165 static int tegra_dc_probe(struct platform_device
*pdev
)
3167 u64 dma_mask
= dma_get_mask(pdev
->dev
.parent
);
3168 struct tegra_dc
*dc
;
3171 err
= dma_coerce_mask_and_coherent(&pdev
->dev
, dma_mask
);
3173 dev_err(&pdev
->dev
, "failed to set DMA mask: %d\n", err
);
3177 dc
= devm_kzalloc(&pdev
->dev
, sizeof(*dc
), GFP_KERNEL
);
3181 dc
->soc
= of_device_get_match_data(&pdev
->dev
);
3183 INIT_LIST_HEAD(&dc
->list
);
3184 dc
->dev
= &pdev
->dev
;
3186 err
= tegra_dc_parse_dt(dc
);
3190 err
= tegra_dc_couple(dc
);
3194 dc
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
3195 if (IS_ERR(dc
->clk
)) {
3196 dev_err(&pdev
->dev
, "failed to get clock\n");
3197 return PTR_ERR(dc
->clk
);
3200 dc
->rst
= devm_reset_control_get(&pdev
->dev
, "dc");
3201 if (IS_ERR(dc
->rst
)) {
3202 dev_err(&pdev
->dev
, "failed to get reset\n");
3203 return PTR_ERR(dc
->rst
);
3206 /* assert reset and disable clock */
3207 err
= clk_prepare_enable(dc
->clk
);
3211 usleep_range(2000, 4000);
3213 err
= reset_control_assert(dc
->rst
);
3215 clk_disable_unprepare(dc
->clk
);
3219 usleep_range(2000, 4000);
3221 clk_disable_unprepare(dc
->clk
);
3223 if (dc
->soc
->has_powergate
) {
3225 dc
->powergate
= TEGRA_POWERGATE_DIS
;
3227 dc
->powergate
= TEGRA_POWERGATE_DISB
;
3229 tegra_powergate_power_off(dc
->powergate
);
3232 err
= tegra_dc_init_opp_table(dc
);
3236 dc
->regs
= devm_platform_ioremap_resource(pdev
, 0);
3237 if (IS_ERR(dc
->regs
))
3238 return PTR_ERR(dc
->regs
);
3240 dc
->irq
= platform_get_irq(pdev
, 0);
3244 err
= tegra_dc_rgb_probe(dc
);
3245 if (err
< 0 && err
!= -ENODEV
)
3246 return dev_err_probe(&pdev
->dev
, err
,
3247 "failed to probe RGB output\n");
3249 platform_set_drvdata(pdev
, dc
);
3250 pm_runtime_enable(&pdev
->dev
);
3252 INIT_LIST_HEAD(&dc
->client
.list
);
3253 dc
->client
.ops
= &dc_client_ops
;
3254 dc
->client
.dev
= &pdev
->dev
;
3256 err
= host1x_client_register(&dc
->client
);
3258 dev_err(&pdev
->dev
, "failed to register host1x client: %d\n",
3266 pm_runtime_disable(&pdev
->dev
);
3267 tegra_dc_rgb_remove(dc
);
3272 static void tegra_dc_remove(struct platform_device
*pdev
)
3274 struct tegra_dc
*dc
= platform_get_drvdata(pdev
);
3276 host1x_client_unregister(&dc
->client
);
3278 tegra_dc_rgb_remove(dc
);
3280 pm_runtime_disable(&pdev
->dev
);
3283 struct platform_driver tegra_dc_driver
= {
3286 .of_match_table
= tegra_dc_of_match
,
3288 .probe
= tegra_dc_probe
,
3289 .remove
= tegra_dc_remove
,