@@ -454,7 +454,9 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
454454 unsigned int zpos = new_state -> normalized_zpos ;
455455 struct drm_framebuffer * fb = new_state -> fb ;
456456 struct tegra_plane * p = to_tegra_plane (plane );
457- dma_addr_t base ;
457+ dma_addr_t base , addr_flag = 0 ;
458+ unsigned int bpc ;
459+ bool yuv , planar ;
458460 u32 value ;
459461 int err ;
460462
@@ -473,6 +475,8 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
473475 return ;
474476 }
475477
478+ yuv = tegra_plane_format_is_yuv (tegra_plane_state -> format , & planar , & bpc );
479+
476480 tegra_dc_assign_shared_plane (dc , p );
477481
478482 tegra_plane_writel (p , VCOUNTER , DC_WIN_CORE_ACT_CONTROL );
@@ -501,18 +505,19 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
501505 /* disable compression */
502506 tegra_plane_writel (p , 0 , DC_WINBUF_CDE_CONTROL );
503507
504- base = tegra_plane_state -> iova [0 ] + fb -> offsets [0 ];
505-
506508#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
507509 /*
508510 * Physical address bit 39 in Tegra194 is used as a switch for special
509511 * logic that swizzles the memory using either the legacy Tegra or the
510512 * dGPU sector layout.
511513 */
512514 if (tegra_plane_state -> tiling .sector_layout == TEGRA_BO_SECTOR_LAYOUT_GPU )
513- base | = BIT_ULL (39 );
515+ addr_flag = BIT_ULL (39 );
514516#endif
515517
518+ base = tegra_plane_state -> iova [0 ] + fb -> offsets [0 ];
519+ base |= addr_flag ;
520+
516521 tegra_plane_writel (p , tegra_plane_state -> format , DC_WIN_COLOR_DEPTH );
517522 tegra_plane_writel (p , 0 , DC_WIN_PRECOMP_WGRP_PARAMS );
518523
@@ -535,7 +540,44 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
535540 value = PITCH (fb -> pitches [0 ]);
536541 tegra_plane_writel (p , value , DC_WIN_PLANAR_STORAGE );
537542
538- value = CLAMP_BEFORE_BLEND | DEGAMMA_SRGB | INPUT_RANGE_FULL ;
543+ if (yuv && planar ) {
544+ base = tegra_plane_state -> iova [1 ] + fb -> offsets [1 ];
545+ base |= addr_flag ;
546+
547+ tegra_plane_writel (p , upper_32_bits (base ), DC_WINBUF_START_ADDR_HI_U );
548+ tegra_plane_writel (p , lower_32_bits (base ), DC_WINBUF_START_ADDR_U );
549+
550+ base = tegra_plane_state -> iova [2 ] + fb -> offsets [2 ];
551+ base |= addr_flag ;
552+
553+ tegra_plane_writel (p , upper_32_bits (base ), DC_WINBUF_START_ADDR_HI_V );
554+ tegra_plane_writel (p , lower_32_bits (base ), DC_WINBUF_START_ADDR_V );
555+
556+ value = PITCH_U (fb -> pitches [2 ]) | PITCH_V (fb -> pitches [2 ]);
557+ tegra_plane_writel (p , value , DC_WIN_PLANAR_STORAGE_UV );
558+ } else {
559+ tegra_plane_writel (p , 0 , DC_WINBUF_START_ADDR_U );
560+ tegra_plane_writel (p , 0 , DC_WINBUF_START_ADDR_HI_U );
561+ tegra_plane_writel (p , 0 , DC_WINBUF_START_ADDR_V );
562+ tegra_plane_writel (p , 0 , DC_WINBUF_START_ADDR_HI_V );
563+ tegra_plane_writel (p , 0 , DC_WIN_PLANAR_STORAGE_UV );
564+ }
565+
566+ value = CLAMP_BEFORE_BLEND | INPUT_RANGE_FULL ;
567+
568+ if (yuv ) {
569+ if (bpc < 12 )
570+ value |= DEGAMMA_YUV8_10 ;
571+ else
572+ value |= DEGAMMA_YUV12 ;
573+
574+ /* XXX parameterize */
575+ value |= COLOR_SPACE_YUV_2020 ;
576+ } else {
577+ if (!tegra_plane_format_is_indexed (tegra_plane_state -> format ))
578+ value |= DEGAMMA_SRGB ;
579+ }
580+
539581 tegra_plane_writel (p , value , DC_WIN_SET_PARAMS );
540582
541583 value = OFFSET_X (new_state -> src_y >> 16 ) |
0 commit comments