13
13
#include <linux/platform_device.h>
14
14
#include <linux/clk.h>
15
15
#include <linux/component.h>
16
+ #include <linux/iopoll.h>
16
17
#include <linux/mfd/syscon.h>
17
18
#include <linux/of_device.h>
18
19
#include <linux/of_gpio.h>
33
34
#define WINDOWS_NR 3
34
35
#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
35
36
36
- #define IFTYPE_I80 (1 << 0)
37
- #define I80_HW_TRG (1 << 1)
38
- #define IFTYPE_HDMI (1 << 2)
37
+ #define I80_HW_TRG (1 << 0)
38
+ #define IFTYPE_HDMI (1 << 1)
39
39
40
40
static const char * const decon_clks_name [] = {
41
41
"pclk" ,
@@ -57,6 +57,8 @@ struct decon_context {
57
57
struct regmap * sysreg ;
58
58
struct clk * clks [ARRAY_SIZE (decon_clks_name )];
59
59
unsigned int irq ;
60
+ unsigned int irq_vsync ;
61
+ unsigned int irq_lcd_sys ;
60
62
unsigned int te_irq ;
61
63
unsigned long out_type ;
62
64
int first_win ;
@@ -90,7 +92,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
90
92
u32 val ;
91
93
92
94
val = VIDINTCON0_INTEN ;
93
- if (ctx -> out_type & IFTYPE_I80 )
95
+ if (crtc -> i80_mode )
94
96
val |= VIDINTCON0_FRAMEDONE ;
95
97
else
96
98
val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP ;
@@ -139,7 +141,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
139
141
140
142
switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE )) {
141
143
case VIDCON1_VSTATUS_VS :
142
- if (!(ctx -> out_type & IFTYPE_I80 ))
144
+ if (!(ctx -> crtc -> i80_mode ))
143
145
-- frm ;
144
146
break ;
145
147
case VIDCON1_VSTATUS_BP :
@@ -166,7 +168,7 @@ static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
166
168
167
169
static void decon_setup_trigger (struct decon_context * ctx )
168
170
{
169
- if (!( ctx -> out_type & ( IFTYPE_I80 | I80_HW_TRG ) ))
171
+ if (!ctx -> crtc -> i80_mode && !( ctx -> out_type & I80_HW_TRG ))
170
172
return ;
171
173
172
174
if (!(ctx -> out_type & I80_HW_TRG )) {
@@ -206,7 +208,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
206
208
val = VIDOUT_LCD_ON ;
207
209
if (interlaced )
208
210
val |= VIDOUT_INTERLACE_EN_F ;
209
- if (ctx -> out_type & IFTYPE_I80 ) {
211
+ if (crtc -> i80_mode ) {
210
212
val |= VIDOUT_COMMAND_IF ;
211
213
} else {
212
214
val |= VIDOUT_RGB_IF ;
@@ -222,7 +224,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
222
224
VIDTCON2_HOZVAL (m -> hdisplay - 1 );
223
225
writel (val , ctx -> addr + DECON_VIDTCON2 );
224
226
225
- if (!( ctx -> out_type & IFTYPE_I80 ) ) {
227
+ if (!crtc -> i80_mode ) {
226
228
int vbp = m -> crtc_vtotal - m -> crtc_vsync_end ;
227
229
int vfp = m -> crtc_vsync_start - m -> crtc_vdisplay ;
228
230
@@ -277,16 +279,14 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
277
279
val |= WINCONx_BURSTLEN_16WORD ;
278
280
break ;
279
281
case DRM_FORMAT_ARGB8888 :
282
+ default :
280
283
val |= WINCONx_BPPMODE_32BPP_A8888 ;
281
284
val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F ;
282
285
val |= WINCONx_BURSTLEN_16WORD ;
283
286
break ;
284
- default :
285
- DRM_ERROR ("Proper pixel format is not set\n" );
286
- return ;
287
287
}
288
288
289
- DRM_DEBUG_KMS ("bpp = %u\n" , fb -> format -> cpp [0 ] * 8 );
289
+ DRM_DEBUG_KMS ("cpp = %u\n" , fb -> format -> cpp [0 ]);
290
290
291
291
/*
292
292
* In case of exynos, setting dma-burst to 16Word causes permanent
@@ -329,7 +329,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
329
329
struct decon_context * ctx = crtc -> ctx ;
330
330
struct drm_framebuffer * fb = state -> base .fb ;
331
331
unsigned int win = plane -> index ;
332
- unsigned int bpp = fb -> format -> cpp [0 ];
332
+ unsigned int cpp = fb -> format -> cpp [0 ];
333
333
unsigned int pitch = fb -> pitches [0 ];
334
334
dma_addr_t dma_addr = exynos_drm_fb_dma_addr (fb , 0 );
335
335
u32 val ;
@@ -365,11 +365,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
365
365
writel (val , ctx -> addr + DECON_VIDW0xADD1B0 (win ));
366
366
367
367
if (!(ctx -> out_type & IFTYPE_HDMI ))
368
- val = BIT_VAL (pitch - state -> crtc .w * bpp , 27 , 14 )
369
- | BIT_VAL (state -> crtc .w * bpp , 13 , 0 );
368
+ val = BIT_VAL (pitch - state -> crtc .w * cpp , 27 , 14 )
369
+ | BIT_VAL (state -> crtc .w * cpp , 13 , 0 );
370
370
else
371
- val = BIT_VAL (pitch - state -> crtc .w * bpp , 29 , 15 )
372
- | BIT_VAL (state -> crtc .w * bpp , 14 , 0 );
371
+ val = BIT_VAL (pitch - state -> crtc .w * cpp , 29 , 15 )
372
+ | BIT_VAL (state -> crtc .w * cpp , 14 , 0 );
373
373
writel (val , ctx -> addr + DECON_VIDW0xADD2 (win ));
374
374
375
375
decon_win_set_pixfmt (ctx , win , fb );
@@ -407,24 +407,19 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
407
407
408
408
static void decon_swreset (struct decon_context * ctx )
409
409
{
410
- unsigned int tries ;
411
410
unsigned long flags ;
411
+ u32 val ;
412
+ int ret ;
412
413
413
414
writel (0 , ctx -> addr + DECON_VIDCON0 );
414
- for (tries = 2000 ; tries ; -- tries ) {
415
- if (~readl (ctx -> addr + DECON_VIDCON0 ) & VIDCON0_STOP_STATUS )
416
- break ;
417
- udelay (10 );
418
- }
415
+ readl_poll_timeout (ctx -> addr + DECON_VIDCON0 , val ,
416
+ ~val & VIDCON0_STOP_STATUS , 12 , 20000 );
419
417
420
418
writel (VIDCON0_SWRESET , ctx -> addr + DECON_VIDCON0 );
421
- for (tries = 2000 ; tries ; -- tries ) {
422
- if (~readl (ctx -> addr + DECON_VIDCON0 ) & VIDCON0_SWRESET )
423
- break ;
424
- udelay (10 );
425
- }
419
+ ret = readl_poll_timeout (ctx -> addr + DECON_VIDCON0 , val ,
420
+ ~val & VIDCON0_SWRESET , 12 , 20000 );
426
421
427
- WARN (tries == 0 , "failed to software reset DECON\n" );
422
+ WARN (ret < 0 , "failed to software reset DECON\n" );
428
423
429
424
spin_lock_irqsave (& ctx -> vblank_lock , flags );
430
425
ctx -> frame_id = 0 ;
@@ -515,6 +510,22 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
515
510
clk_disable_unprepare (ctx -> clks [i ]);
516
511
}
517
512
513
+ static enum drm_mode_status decon_mode_valid (struct exynos_drm_crtc * crtc ,
514
+ const struct drm_display_mode * mode )
515
+ {
516
+ struct decon_context * ctx = crtc -> ctx ;
517
+
518
+ ctx -> irq = crtc -> i80_mode ? ctx -> irq_lcd_sys : ctx -> irq_vsync ;
519
+
520
+ if (ctx -> irq )
521
+ return MODE_OK ;
522
+
523
+ dev_info (ctx -> dev , "Sink requires %s mode, but appropriate interrupt is not provided.\n" ,
524
+ crtc -> i80_mode ? "command" : "video" );
525
+
526
+ return MODE_BAD ;
527
+ }
528
+
518
529
static const struct exynos_drm_crtc_ops decon_crtc_ops = {
519
530
.enable = decon_enable ,
520
531
.disable = decon_disable ,
@@ -524,6 +535,7 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
524
535
.atomic_begin = decon_atomic_begin ,
525
536
.update_plane = decon_update_plane ,
526
537
.disable_plane = decon_disable_plane ,
538
+ .mode_valid = decon_mode_valid ,
527
539
.atomic_flush = decon_atomic_flush ,
528
540
};
529
541
@@ -674,19 +686,22 @@ static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
674
686
MODULE_DEVICE_TABLE (of , exynos5433_decon_driver_dt_match );
675
687
676
688
static int decon_conf_irq (struct decon_context * ctx , const char * name ,
677
- irq_handler_t handler , unsigned long int flags , bool required )
689
+ irq_handler_t handler , unsigned long int flags )
678
690
{
679
691
struct platform_device * pdev = to_platform_device (ctx -> dev );
680
692
int ret , irq = platform_get_irq_byname (pdev , name );
681
693
682
694
if (irq < 0 ) {
683
- if (irq == - EPROBE_DEFER )
695
+ switch (irq ) {
696
+ case - EPROBE_DEFER :
684
697
return irq ;
685
- if (required )
686
- dev_err (ctx -> dev , "cannot get %s IRQ\n" , name );
687
- else
688
- irq = 0 ;
689
- return irq ;
698
+ case - ENODATA :
699
+ case - ENXIO :
700
+ return 0 ;
701
+ default :
702
+ dev_err (ctx -> dev , "IRQ %s get failed, %d\n" , name , irq );
703
+ return irq ;
704
+ }
690
705
}
691
706
irq_set_status_flags (irq , IRQ_NOAUTOEN );
692
707
ret = devm_request_irq (ctx -> dev , irq , handler , flags , "drm_decon" , ctx );
@@ -714,11 +729,8 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
714
729
ctx -> out_type = (unsigned long )of_device_get_match_data (dev );
715
730
spin_lock_init (& ctx -> vblank_lock );
716
731
717
- if (ctx -> out_type & IFTYPE_HDMI ) {
732
+ if (ctx -> out_type & IFTYPE_HDMI )
718
733
ctx -> first_win = 1 ;
719
- } else if (of_get_child_by_name (dev -> of_node , "i80-if-timings" )) {
720
- ctx -> out_type |= IFTYPE_I80 ;
721
- }
722
734
723
735
for (i = 0 ; i < ARRAY_SIZE (decon_clks_name ); i ++ ) {
724
736
struct clk * clk ;
@@ -742,25 +754,23 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
742
754
return PTR_ERR (ctx -> addr );
743
755
}
744
756
745
- if (ctx -> out_type & IFTYPE_I80 ) {
746
- ret = decon_conf_irq (ctx , "lcd_sys" , decon_irq_handler , 0 , true);
747
- if (ret < 0 )
748
- return ret ;
749
- ctx -> irq = ret ;
757
+ ret = decon_conf_irq (ctx , "vsync" , decon_irq_handler , 0 );
758
+ if (ret < 0 )
759
+ return ret ;
760
+ ctx -> irq_vsync = ret ;
750
761
751
- ret = decon_conf_irq (ctx , "te" , decon_te_irq_handler ,
752
- IRQF_TRIGGER_RISING , false);
753
- if (ret < 0 )
754
- return ret ;
755
- if (ret ) {
756
- ctx -> te_irq = ret ;
757
- ctx -> out_type &= ~I80_HW_TRG ;
758
- }
759
- } else {
760
- ret = decon_conf_irq (ctx , "vsync" , decon_irq_handler , 0 , true);
761
- if (ret < 0 )
762
+ ret = decon_conf_irq (ctx , "lcd_sys" , decon_irq_handler , 0 );
763
+ if (ret < 0 )
764
+ return ret ;
765
+ ctx -> irq_lcd_sys = ret ;
766
+
767
+ ret = decon_conf_irq (ctx , "te" , decon_te_irq_handler ,
768
+ IRQF_TRIGGER_RISING );
769
+ if (ret < 0 )
762
770
return ret ;
763
- ctx -> irq = ret ;
771
+ if (ret ) {
772
+ ctx -> te_irq = ret ;
773
+ ctx -> out_type &= ~I80_HW_TRG ;
764
774
}
765
775
766
776
if (ctx -> out_type & I80_HW_TRG ) {
0 commit comments