@@ -626,19 +626,213 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
626
626
}
627
627
}
628
628
629
+ static u8 * goto_next_sequence (u8 * data , int * size )
630
+ {
631
+ u16 len ;
632
+ int tmp = * size ;
633
+
634
+ if (-- tmp < 0 )
635
+ return NULL ;
636
+
637
+ /* goto first element */
638
+ data ++ ;
639
+ while (1 ) {
640
+ switch (* data ) {
641
+ case MIPI_SEQ_ELEM_SEND_PKT :
642
+ /*
643
+ * skip by this element payload size
644
+ * skip elem id, command flag and data type
645
+ */
646
+ if ((tmp = tmp - 5 ) < 0 )
647
+ return NULL ;
648
+
649
+ data += 3 ;
650
+ len = * ((u16 * )data );
651
+
652
+ if ((tmp = tmp - len ) < 0 )
653
+ return NULL ;
654
+
655
+ /* skip by len */
656
+ data = data + 2 + len ;
657
+ break ;
658
+ case MIPI_SEQ_ELEM_DELAY :
659
+ /* skip by elem id, and delay is 4 bytes */
660
+ if ((tmp = tmp - 5 ) < 0 )
661
+ return NULL ;
662
+
663
+ data += 5 ;
664
+ break ;
665
+ case MIPI_SEQ_ELEM_GPIO :
666
+ if ((tmp = tmp - 3 ) < 0 )
667
+ return NULL ;
668
+
669
+ data += 3 ;
670
+ break ;
671
+ default :
672
+ DRM_ERROR ("Unknown element\n" );
673
+ return NULL ;
674
+ }
675
+
676
+ /* end of sequence ? */
677
+ if (* data == 0 )
678
+ break ;
679
+ }
680
+
681
+ /* goto next sequence or end of block byte */
682
+ if (-- tmp < 0 )
683
+ return NULL ;
684
+
685
+ data ++ ;
686
+
687
+ /* update amount of data left for the sequence block to be parsed */
688
+ * size = tmp ;
689
+ return data ;
690
+ }
691
+
629
692
static void
630
693
parse_mipi (struct drm_i915_private * dev_priv , struct bdb_header * bdb )
631
694
{
632
- struct bdb_mipi * mipi ;
695
+ struct bdb_mipi_config * start ;
696
+ struct bdb_mipi_sequence * sequence ;
697
+ struct mipi_config * config ;
698
+ struct mipi_pps_data * pps ;
699
+ u8 * data , * seq_data ;
700
+ int i , panel_id , seq_size ;
701
+ u16 block_size ;
702
+
703
+ /* Initialize this to undefined indicating no generic MIPI support */
704
+ dev_priv -> vbt .dsi .panel_id = MIPI_DSI_UNDEFINED_PANEL_ID ;
705
+
706
+ /* Block #40 is already parsed and panel_fixed_mode is
707
+ * stored in dev_priv->lfp_lvds_vbt_mode
708
+ * resuse this when needed
709
+ */
633
710
634
- mipi = find_section (bdb , BDB_MIPI_CONFIG );
635
- if (!mipi ) {
636
- DRM_DEBUG_KMS ("No MIPI BDB found" );
711
+ /* Parse #52 for panel index used from panel_type already
712
+ * parsed
713
+ */
714
+ start = find_section (bdb , BDB_MIPI_CONFIG );
715
+ if (!start ) {
716
+ DRM_DEBUG_KMS ("No MIPI config BDB found" );
637
717
return ;
638
718
}
639
719
640
- /* XXX: add more info */
720
+ DRM_DEBUG_DRIVER ("Found MIPI Config block, panel index = %d\n" ,
721
+ panel_type );
722
+
723
+ /*
724
+ * get hold of the correct configuration block and pps data as per
725
+ * the panel_type as index
726
+ */
727
+ config = & start -> config [panel_type ];
728
+ pps = & start -> pps [panel_type ];
729
+
730
+ /* store as of now full data. Trim when we realise all is not needed */
731
+ dev_priv -> vbt .dsi .config = kmemdup (config , sizeof (struct mipi_config ), GFP_KERNEL );
732
+ if (!dev_priv -> vbt .dsi .config )
733
+ return ;
734
+
735
+ dev_priv -> vbt .dsi .pps = kmemdup (pps , sizeof (struct mipi_pps_data ), GFP_KERNEL );
736
+ if (!dev_priv -> vbt .dsi .pps ) {
737
+ kfree (dev_priv -> vbt .dsi .config );
738
+ return ;
739
+ }
740
+
741
+ /* We have mandatory mipi config blocks. Initialize as generic panel */
641
742
dev_priv -> vbt .dsi .panel_id = MIPI_DSI_GENERIC_PANEL_ID ;
743
+
744
+ /* Check if we have sequence block as well */
745
+ sequence = find_section (bdb , BDB_MIPI_SEQUENCE );
746
+ if (!sequence ) {
747
+ DRM_DEBUG_KMS ("No MIPI Sequence found, parsing complete\n" );
748
+ return ;
749
+ }
750
+
751
+ DRM_DEBUG_DRIVER ("Found MIPI sequence block\n" );
752
+
753
+ block_size = get_blocksize (sequence );
754
+
755
+ /*
756
+ * parse the sequence block for individual sequences
757
+ */
758
+ dev_priv -> vbt .dsi .seq_version = sequence -> version ;
759
+
760
+ seq_data = & sequence -> data [0 ];
761
+
762
+ /*
763
+ * sequence block is variable length and hence we need to parse and
764
+ * get the sequence data for specific panel id
765
+ */
766
+ for (i = 0 ; i < MAX_MIPI_CONFIGURATIONS ; i ++ ) {
767
+ panel_id = * seq_data ;
768
+ seq_size = * ((u16 * ) (seq_data + 1 ));
769
+ if (panel_id == panel_type )
770
+ break ;
771
+
772
+ /* skip the sequence including seq header of 3 bytes */
773
+ seq_data = seq_data + 3 + seq_size ;
774
+ if ((seq_data - & sequence -> data [0 ]) > block_size ) {
775
+ DRM_ERROR ("Sequence start is beyond sequence block size, corrupted sequence block\n" );
776
+ return ;
777
+ }
778
+ }
779
+
780
+ if (i == MAX_MIPI_CONFIGURATIONS ) {
781
+ DRM_ERROR ("Sequence block detected but no valid configuration\n" );
782
+ return ;
783
+ }
784
+
785
+ /* check if found sequence is completely within the sequence block
786
+ * just being paranoid */
787
+ if (seq_size > block_size ) {
788
+ DRM_ERROR ("Corrupted sequence/size, bailing out\n" );
789
+ return ;
790
+ }
791
+
792
+ /* skip the panel id(1 byte) and seq size(2 bytes) */
793
+ dev_priv -> vbt .dsi .data = kmemdup (seq_data + 3 , seq_size , GFP_KERNEL );
794
+ if (!dev_priv -> vbt .dsi .data )
795
+ return ;
796
+
797
+ /*
798
+ * loop into the sequence data and split into multiple sequneces
799
+ * There are only 5 types of sequences as of now
800
+ */
801
+ data = dev_priv -> vbt .dsi .data ;
802
+ dev_priv -> vbt .dsi .size = seq_size ;
803
+
804
+ /* two consecutive 0x00 indicate end of all sequences */
805
+ while (1 ) {
806
+ int seq_id = * data ;
807
+ if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED ) {
808
+ dev_priv -> vbt .dsi .sequence [seq_id ] = data ;
809
+ DRM_DEBUG_DRIVER ("Found mipi sequence - %d\n" , seq_id );
810
+ } else {
811
+ DRM_ERROR ("undefined sequence\n" );
812
+ goto err ;
813
+ }
814
+
815
+ /* partial parsing to skip elements */
816
+ data = goto_next_sequence (data , & seq_size );
817
+
818
+ if (data == NULL ) {
819
+ DRM_ERROR ("Sequence elements going beyond block itself. Sequence block parsing failed\n" );
820
+ goto err ;
821
+ }
822
+
823
+ if (* data == 0 )
824
+ break ; /* end of sequence reached */
825
+ }
826
+
827
+ DRM_DEBUG_DRIVER ("MIPI related vbt parsing complete\n" );
828
+ return ;
829
+ err :
830
+ kfree (dev_priv -> vbt .dsi .data );
831
+ dev_priv -> vbt .dsi .data = NULL ;
832
+
833
+ /* error during parsing so set all pointers to null
834
+ * because of partial parsing */
835
+ memset (dev_priv -> vbt .dsi .sequence , 0 , MIPI_SEQ_MAX );
642
836
}
643
837
644
838
static void parse_ddi_port (struct drm_i915_private * dev_priv , enum port port ,
0 commit comments