13
13
#include <linux/pm_runtime.h>
14
14
#include <linux/regmap.h>
15
15
#include <linux/reset.h>
16
+ #include <linux/slab.h>
16
17
17
18
#include <linux/phy/phy.h>
18
19
@@ -247,10 +248,8 @@ static u16 sun6i_dsi_crc_compute(u8 const *buffer, size_t len)
247
248
return crc_ccitt (0xffff , buffer , len );
248
249
}
249
250
250
- static u16 sun6i_dsi_crc_repeat_compute (u8 pd , size_t len )
251
+ static u16 sun6i_dsi_crc_repeat (u8 pd , u8 * buffer , size_t len )
251
252
{
252
- u8 buffer [len ];
253
-
254
253
memset (buffer , pd , len );
255
254
256
255
return sun6i_dsi_crc_compute (buffer , len );
@@ -274,11 +273,11 @@ static u32 sun6i_dsi_build_blk0_pkt(u8 vc, u16 wc)
274
273
wc & 0xff , wc >> 8 );
275
274
}
276
275
277
- static u32 sun6i_dsi_build_blk1_pkt (u16 pd , size_t len )
276
+ static u32 sun6i_dsi_build_blk1_pkt (u16 pd , u8 * buffer , size_t len )
278
277
{
279
278
u32 val = SUN6I_DSI_BLK_PD (pd );
280
279
281
- return val | SUN6I_DSI_BLK_PF (sun6i_dsi_crc_repeat_compute (pd , len ));
280
+ return val | SUN6I_DSI_BLK_PF (sun6i_dsi_crc_repeat (pd , buffer , len ));
282
281
}
283
282
284
283
static void sun6i_dsi_inst_abort (struct sun6i_dsi * dsi )
@@ -452,6 +451,54 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
452
451
struct mipi_dsi_device * device = dsi -> device ;
453
452
unsigned int Bpp = mipi_dsi_pixel_format_to_bpp (device -> format ) / 8 ;
454
453
u16 hbp , hfp , hsa , hblk , vblk ;
454
+ size_t bytes ;
455
+ u8 * buffer ;
456
+
457
+ /* Do all timing calculations up front to allocate buffer space */
458
+
459
+ /*
460
+ * A sync period is composed of a blanking packet (4 bytes +
461
+ * payload + 2 bytes) and a sync event packet (4 bytes). Its
462
+ * minimal size is therefore 10 bytes
463
+ */
464
+ #define HSA_PACKET_OVERHEAD 10
465
+ hsa = max ((unsigned int )HSA_PACKET_OVERHEAD ,
466
+ (mode -> hsync_end - mode -> hsync_start ) * Bpp - HSA_PACKET_OVERHEAD );
467
+
468
+ /*
469
+ * The backporch is set using a blanking packet (4 bytes +
470
+ * payload + 2 bytes). Its minimal size is therefore 6 bytes
471
+ */
472
+ #define HBP_PACKET_OVERHEAD 6
473
+ hbp = max ((unsigned int )HBP_PACKET_OVERHEAD ,
474
+ (mode -> hsync_start - mode -> hdisplay ) * Bpp - HBP_PACKET_OVERHEAD );
475
+
476
+ /*
477
+ * The frontporch is set using a blanking packet (4 bytes +
478
+ * payload + 2 bytes). Its minimal size is therefore 6 bytes
479
+ */
480
+ #define HFP_PACKET_OVERHEAD 6
481
+ hfp = max ((unsigned int )HFP_PACKET_OVERHEAD ,
482
+ (mode -> htotal - mode -> hsync_end ) * Bpp - HFP_PACKET_OVERHEAD );
483
+
484
+ /*
485
+ * hblk seems to be the line + porches length.
486
+ */
487
+ hblk = mode -> htotal * Bpp - hsa ;
488
+
489
+ /*
490
+ * And I'm not entirely sure what vblk is about. The driver in
491
+ * Allwinner BSP is using a rather convoluted calculation
492
+ * there only for 4 lanes. However, using 0 (the !4 lanes
493
+ * case) even with a 4 lanes screen seems to work...
494
+ */
495
+ vblk = 0 ;
496
+
497
+ /* How many bytes do we need to send all payloads? */
498
+ bytes = max_t (size_t , max (max (hfp , hblk ), max (hsa , hbp )), vblk );
499
+ buffer = kmalloc (bytes , GFP_KERNEL );
500
+ if (WARN_ON (!buffer ))
501
+ return ;
455
502
456
503
regmap_write (dsi -> regs , SUN6I_DSI_BASIC_CTL_REG , 0 );
457
504
@@ -485,63 +532,37 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
485
532
SUN6I_DSI_BASIC_SIZE1_VACT (mode -> vdisplay ) |
486
533
SUN6I_DSI_BASIC_SIZE1_VT (mode -> vtotal ));
487
534
488
- /*
489
- * A sync period is composed of a blanking packet (4 bytes +
490
- * payload + 2 bytes) and a sync event packet (4 bytes). Its
491
- * minimal size is therefore 10 bytes
492
- */
493
- #define HSA_PACKET_OVERHEAD 10
494
- hsa = max ((unsigned int )HSA_PACKET_OVERHEAD ,
495
- (mode -> hsync_end - mode -> hsync_start ) * Bpp - HSA_PACKET_OVERHEAD );
535
+ /* sync */
496
536
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HSA0_REG ,
497
537
sun6i_dsi_build_blk0_pkt (device -> channel , hsa ));
498
538
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HSA1_REG ,
499
- sun6i_dsi_build_blk1_pkt (0 , hsa ));
539
+ sun6i_dsi_build_blk1_pkt (0 , buffer , hsa ));
500
540
501
- /*
502
- * The backporch is set using a blanking packet (4 bytes +
503
- * payload + 2 bytes). Its minimal size is therefore 6 bytes
504
- */
505
- #define HBP_PACKET_OVERHEAD 6
506
- hbp = max ((unsigned int )HBP_PACKET_OVERHEAD ,
507
- (mode -> hsync_start - mode -> hdisplay ) * Bpp - HBP_PACKET_OVERHEAD );
541
+ /* backporch */
508
542
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HBP0_REG ,
509
543
sun6i_dsi_build_blk0_pkt (device -> channel , hbp ));
510
544
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HBP1_REG ,
511
- sun6i_dsi_build_blk1_pkt (0 , hbp ));
545
+ sun6i_dsi_build_blk1_pkt (0 , buffer , hbp ));
512
546
513
- /*
514
- * The frontporch is set using a blanking packet (4 bytes +
515
- * payload + 2 bytes). Its minimal size is therefore 6 bytes
516
- */
517
- #define HFP_PACKET_OVERHEAD 6
518
- hfp = max ((unsigned int )HFP_PACKET_OVERHEAD ,
519
- (mode -> htotal - mode -> hsync_end ) * Bpp - HFP_PACKET_OVERHEAD );
547
+ /* frontporch */
520
548
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HFP0_REG ,
521
549
sun6i_dsi_build_blk0_pkt (device -> channel , hfp ));
522
550
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HFP1_REG ,
523
- sun6i_dsi_build_blk1_pkt (0 , hfp ));
551
+ sun6i_dsi_build_blk1_pkt (0 , buffer , hfp ));
524
552
525
- /*
526
- * hblk seems to be the line + porches length.
527
- */
528
- hblk = mode -> htotal * Bpp - hsa ;
553
+ /* hblk */
529
554
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HBLK0_REG ,
530
555
sun6i_dsi_build_blk0_pkt (device -> channel , hblk ));
531
556
regmap_write (dsi -> regs , SUN6I_DSI_BLK_HBLK1_REG ,
532
- sun6i_dsi_build_blk1_pkt (0 , hblk ));
557
+ sun6i_dsi_build_blk1_pkt (0 , buffer , hblk ));
533
558
534
- /*
535
- * And I'm not entirely sure what vblk is about. The driver in
536
- * Allwinner BSP is using a rather convoluted calculation
537
- * there only for 4 lanes. However, using 0 (the !4 lanes
538
- * case) even with a 4 lanes screen seems to work...
539
- */
540
- vblk = 0 ;
559
+ /* vblk */
541
560
regmap_write (dsi -> regs , SUN6I_DSI_BLK_VBLK0_REG ,
542
561
sun6i_dsi_build_blk0_pkt (device -> channel , vblk ));
543
562
regmap_write (dsi -> regs , SUN6I_DSI_BLK_VBLK1_REG ,
544
- sun6i_dsi_build_blk1_pkt (0 , vblk ));
563
+ sun6i_dsi_build_blk1_pkt (0 , buffer , vblk ));
564
+
565
+ kfree (buffer );
545
566
}
546
567
547
568
static int sun6i_dsi_start (struct sun6i_dsi * dsi ,
0 commit comments