3737
3838#define WINDOWS_NR 2
3939
40+ struct decon_data {
41+ unsigned int vidw_buf_start_base ;
42+ unsigned int shadowcon_win_protect_shift ;
43+ unsigned int wincon_burstlen_shift ;
44+ };
45+
46+ static struct decon_data exynos7_decon_data = {
47+ .vidw_buf_start_base = 0x80 ,
48+ .shadowcon_win_protect_shift = 10 ,
49+ .wincon_burstlen_shift = 11 ,
50+ };
51+
52+ static struct decon_data exynos7870_decon_data = {
53+ .vidw_buf_start_base = 0x880 ,
54+ .shadowcon_win_protect_shift = 8 ,
55+ .wincon_burstlen_shift = 10 ,
56+ };
57+
4058struct decon_context {
4159 struct device * dev ;
4260 struct drm_device * drm_dev ;
@@ -55,11 +73,19 @@ struct decon_context {
5573 wait_queue_head_t wait_vsync_queue ;
5674 atomic_t wait_vsync_event ;
5775
76+ const struct decon_data * data ;
5877 struct drm_encoder * encoder ;
5978};
6079
6180static const struct of_device_id decon_driver_dt_match [] = {
62- {.compatible = "samsung,exynos7-decon" },
81+ {
82+ .compatible = "samsung,exynos7-decon" ,
83+ .data = & exynos7_decon_data ,
84+ },
85+ {
86+ .compatible = "samsung,exynos7870-decon" ,
87+ .data = & exynos7870_decon_data ,
88+ },
6389 {},
6490};
6591MODULE_DEVICE_TABLE (of , decon_driver_dt_match );
@@ -92,8 +118,9 @@ static void decon_shadow_protect_win(struct decon_context *ctx,
92118 unsigned int win , bool protect )
93119{
94120 u32 bits , val ;
121+ unsigned int shift = ctx -> data -> shadowcon_win_protect_shift ;
95122
96- bits = SHADOWCON_WINx_PROTECT (win );
123+ bits = SHADOWCON_WINx_PROTECT (shift , win );
97124
98125 val = readl (ctx -> regs + SHADOWCON );
99126 if (protect )
@@ -291,51 +318,52 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
291318{
292319 unsigned long val ;
293320 int padding ;
321+ unsigned int shift = ctx -> data -> wincon_burstlen_shift ;
294322
295323 val = readl (ctx -> regs + WINCON (win ));
296324 val &= ~WINCONx_BPPMODE_MASK ;
297325
298326 switch (fb -> format -> format ) {
299327 case DRM_FORMAT_RGB565 :
300328 val |= WINCONx_BPPMODE_16BPP_565 ;
301- val |= WINCONx_BURSTLEN_16WORD ;
329+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
302330 break ;
303331 case DRM_FORMAT_XRGB8888 :
304332 val |= WINCONx_BPPMODE_24BPP_xRGB ;
305- val |= WINCONx_BURSTLEN_16WORD ;
333+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
306334 break ;
307335 case DRM_FORMAT_XBGR8888 :
308336 val |= WINCONx_BPPMODE_24BPP_xBGR ;
309- val |= WINCONx_BURSTLEN_16WORD ;
337+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
310338 break ;
311339 case DRM_FORMAT_RGBX8888 :
312340 val |= WINCONx_BPPMODE_24BPP_RGBx ;
313- val |= WINCONx_BURSTLEN_16WORD ;
341+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
314342 break ;
315343 case DRM_FORMAT_BGRX8888 :
316344 val |= WINCONx_BPPMODE_24BPP_BGRx ;
317- val |= WINCONx_BURSTLEN_16WORD ;
345+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
318346 break ;
319347 case DRM_FORMAT_ARGB8888 :
320348 val |= WINCONx_BPPMODE_32BPP_ARGB | WINCONx_BLD_PIX |
321349 WINCONx_ALPHA_SEL ;
322- val |= WINCONx_BURSTLEN_16WORD ;
350+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
323351 break ;
324352 case DRM_FORMAT_ABGR8888 :
325353 val |= WINCONx_BPPMODE_32BPP_ABGR | WINCONx_BLD_PIX |
326354 WINCONx_ALPHA_SEL ;
327- val |= WINCONx_BURSTLEN_16WORD ;
355+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
328356 break ;
329357 case DRM_FORMAT_RGBA8888 :
330358 val |= WINCONx_BPPMODE_32BPP_RGBA | WINCONx_BLD_PIX |
331359 WINCONx_ALPHA_SEL ;
332- val |= WINCONx_BURSTLEN_16WORD ;
360+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
333361 break ;
334362 case DRM_FORMAT_BGRA8888 :
335363 default :
336364 val |= WINCONx_BPPMODE_32BPP_BGRA | WINCONx_BLD_PIX |
337365 WINCONx_ALPHA_SEL ;
338- val |= WINCONx_BURSTLEN_16WORD ;
366+ val |= WINCONx_BURSTLEN_16WORD ( shift ) ;
339367 break ;
340368 }
341369
@@ -351,8 +379,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
351379
352380 padding = (fb -> pitches [0 ] / fb -> format -> cpp [0 ]) - fb -> width ;
353381 if (fb -> width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST ) {
354- val &= ~WINCONx_BURSTLEN_MASK ;
355- val |= WINCONx_BURSTLEN_8WORD ;
382+ val &= ~WINCONx_BURSTLEN_MASK ( shift ) ;
383+ val |= WINCONx_BURSTLEN_8WORD ( shift ) ;
356384 }
357385
358386 writel (val , ctx -> regs + WINCON (win ));
@@ -397,6 +425,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
397425 unsigned int win = plane -> index ;
398426 unsigned int cpp = fb -> format -> cpp [0 ];
399427 unsigned int pitch = fb -> pitches [0 ];
428+ unsigned int vidw_addr0_base = ctx -> data -> vidw_buf_start_base ;
400429
401430 if (ctx -> suspended )
402431 return ;
@@ -413,7 +442,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
413442
414443 /* buffer start address */
415444 val = (unsigned long )exynos_drm_fb_dma_addr (fb , 0 );
416- writel (val , ctx -> regs + VIDW_BUF_START (win ));
445+ writel (val , ctx -> regs + VIDW_BUF_START (vidw_addr0_base , win ));
417446
418447 padding = (pitch / cpp ) - fb -> width ;
419448
@@ -695,6 +724,7 @@ static int decon_probe(struct platform_device *pdev)
695724
696725 ctx -> dev = dev ;
697726 ctx -> suspended = true;
727+ ctx -> data = of_device_get_match_data (dev );
698728
699729 i80_if_timings = of_get_child_by_name (dev -> of_node , "i80-if-timings" );
700730 if (i80_if_timings )
0 commit comments