Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6937 | Rev 7144 | ||
---|---|---|---|
Line 29... | Line 29... | ||
29 | #include |
29 | #include |
30 | #include |
30 | #include |
31 | #include "i915_drv.h" |
31 | #include "i915_drv.h" |
32 | #include "intel_bios.h" |
32 | #include "intel_bios.h" |
Line -... | Line 33... | ||
- | 33 | ||
- | 34 | /** |
|
- | 35 | * DOC: Video BIOS Table (VBT) |
|
- | 36 | * |
|
- | 37 | * The Video BIOS Table, or VBT, provides platform and board specific |
|
- | 38 | * configuration information to the driver that is not discoverable or available |
|
- | 39 | * through other means. The configuration is mostly related to display |
|
- | 40 | * hardware. The VBT is available via the ACPI OpRegion or, on older systems, in |
|
- | 41 | * the PCI ROM. |
|
- | 42 | * |
|
- | 43 | * The VBT consists of a VBT Header (defined as &struct vbt_header), a BDB |
|
- | 44 | * Header (&struct bdb_header), and a number of BIOS Data Blocks (BDB) that |
|
- | 45 | * contain the actual configuration information. The VBT Header, and thus the |
|
- | 46 | * VBT, begins with "$VBT" signature. The VBT Header contains the offset of the |
|
- | 47 | * BDB Header. The data blocks are concatenated after the BDB Header. The data |
|
- | 48 | * blocks have a 1-byte Block ID, 2-byte Block Size, and Block Size bytes of |
|
- | 49 | * data. (Block 53, the MIPI Sequence Block is an exception.) |
|
- | 50 | * |
|
- | 51 | * The driver parses the VBT during load. The relevant information is stored in |
|
- | 52 | * driver private data for ease of use, and the actual VBT is not read after |
|
- | 53 | * that. |
|
- | 54 | */ |
|
33 | 55 | ||
34 | #define SLAVE_ADDR1 0x70 |
56 | #define SLAVE_ADDR1 0x70 |
Line 35... | Line 57... | ||
35 | #define SLAVE_ADDR2 0x72 |
57 | #define SLAVE_ADDR2 0x72 |
Line -... | Line 58... | ||
- | 58 | ||
- | 59 | static int panel_type; |
|
- | 60 | ||
- | 61 | /* Get BDB block size given a pointer to Block ID. */ |
|
- | 62 | static u32 _get_blocksize(const u8 *block_base) |
|
- | 63 | { |
|
- | 64 | /* The MIPI Sequence Block v3+ has a separate size field. */ |
|
- | 65 | if (*block_base == BDB_MIPI_SEQUENCE && *(block_base + 3) >= 3) |
|
- | 66 | return *((const u32 *)(block_base + 4)); |
|
- | 67 | else |
|
- | 68 | return *((const u16 *)(block_base + 1)); |
|
- | 69 | } |
|
- | 70 | ||
- | 71 | /* Get BDB block size give a pointer to data after Block ID and Block Size. */ |
|
- | 72 | static u32 get_blocksize(const void *block_data) |
|
- | 73 | { |
|
36 | 74 | return _get_blocksize(block_data - 3); |
|
37 | static int panel_type; |
75 | } |
38 | 76 | ||
39 | static const void * |
77 | static const void * |
40 | find_section(const void *_bdb, int section_id) |
78 | find_section(const void *_bdb, int section_id) |
Line 50... | Line 88... | ||
50 | total = bdb->bdb_size; |
88 | total = bdb->bdb_size; |
Line 51... | Line 89... | ||
51 | 89 | ||
52 | /* walk the sections looking for section_id */ |
90 | /* walk the sections looking for section_id */ |
53 | while (index + 3 < total) { |
91 | while (index + 3 < total) { |
54 | current_id = *(base + index); |
- | |
55 | index++; |
- | |
56 | 92 | current_id = *(base + index); |
|
57 | current_size = *((const u16 *)(base + index)); |
93 | current_size = _get_blocksize(base + index); |
58 | index += 2; |
- | |
59 | - | ||
60 | /* The MIPI Sequence Block v3+ has a separate size field. */ |
- | |
61 | if (current_id == BDB_MIPI_SEQUENCE && *(base + index) >= 3) |
- | |
Line 62... | Line 94... | ||
62 | current_size = *((const u32 *)(base + index + 1)); |
94 | index += 3; |
63 | 95 | ||
Line 64... | Line 96... | ||
64 | if (index + current_size > total) |
96 | if (index + current_size > total) |
Line 71... | Line 103... | ||
71 | } |
103 | } |
Line 72... | Line 104... | ||
72 | 104 | ||
73 | return NULL; |
105 | return NULL; |
Line 74... | Line -... | ||
74 | } |
- | |
75 | - | ||
76 | static u16 |
- | |
77 | get_blocksize(const void *p) |
- | |
78 | { |
- | |
79 | u16 *block_ptr, block_size; |
- | |
80 | - | ||
81 | block_ptr = (u16 *)((char *)p - 2); |
- | |
82 | block_size = *block_ptr; |
- | |
83 | return block_size; |
- | |
84 | } |
106 | } |
85 | 107 | ||
86 | static void |
108 | static void |
87 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
109 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
88 | const struct lvds_dvo_timing *dvo_timing) |
110 | const struct lvds_dvo_timing *dvo_timing) |
Line 673... | Line 695... | ||
673 | 695 | ||
674 | dev_priv->vbt.psr.tp1_wakeup_time = psr_table->tp1_wakeup_time; |
696 | dev_priv->vbt.psr.tp1_wakeup_time = psr_table->tp1_wakeup_time; |
675 | dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time; |
697 | dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time; |
Line 676... | Line -... | ||
676 | } |
- | |
677 | - | ||
678 | static u8 *goto_next_sequence(u8 *data, int *size) |
- | |
679 | { |
- | |
680 | u16 len; |
- | |
681 | int tmp = *size; |
- | |
682 | - | ||
683 | if (--tmp < 0) |
- | |
684 | return NULL; |
- | |
685 | - | ||
686 | /* goto first element */ |
- | |
687 | data++; |
- | |
688 | while (1) { |
- | |
689 | switch (*data) { |
- | |
690 | case MIPI_SEQ_ELEM_SEND_PKT: |
- | |
691 | /* |
- | |
692 | * skip by this element payload size |
- | |
693 | * skip elem id, command flag and data type |
- | |
694 | */ |
- | |
695 | tmp -= 5; |
- | |
696 | if (tmp < 0) |
- | |
697 | return NULL; |
- | |
698 | - | ||
699 | data += 3; |
- | |
700 | len = *((u16 *)data); |
- | |
701 | - | ||
702 | tmp -= len; |
- | |
703 | if (tmp < 0) |
- | |
704 | return NULL; |
- | |
705 | - | ||
706 | /* skip by len */ |
- | |
707 | data = data + 2 + len; |
- | |
708 | break; |
- | |
709 | case MIPI_SEQ_ELEM_DELAY: |
- | |
710 | /* skip by elem id, and delay is 4 bytes */ |
- | |
711 | tmp -= 5; |
- | |
712 | if (tmp < 0) |
- | |
713 | return NULL; |
- | |
714 | - | ||
715 | data += 5; |
- | |
716 | break; |
- | |
717 | case MIPI_SEQ_ELEM_GPIO: |
- | |
718 | tmp -= 3; |
- | |
719 | if (tmp < 0) |
- | |
720 | return NULL; |
- | |
721 | - | ||
722 | data += 3; |
- | |
723 | break; |
- | |
724 | default: |
- | |
725 | DRM_ERROR("Unknown element\n"); |
- | |
726 | return NULL; |
- | |
727 | } |
- | |
728 | - | ||
729 | /* end of sequence ? */ |
- | |
730 | if (*data == 0) |
- | |
731 | break; |
- | |
732 | } |
- | |
733 | - | ||
734 | /* goto next sequence or end of block byte */ |
- | |
735 | if (--tmp < 0) |
- | |
736 | return NULL; |
- | |
737 | - | ||
738 | data++; |
- | |
739 | - | ||
740 | /* update amount of data left for the sequence block to be parsed */ |
- | |
741 | *size = tmp; |
- | |
742 | return data; |
- | |
743 | } |
698 | } |
744 | 699 | ||
- | 700 | static void |
|
745 | static void |
701 | parse_mipi_config(struct drm_i915_private *dev_priv, |
746 | parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) |
702 | const struct bdb_header *bdb) |
747 | { |
- | |
748 | const struct bdb_mipi_config *start; |
703 | { |
749 | const struct bdb_mipi_sequence *sequence; |
704 | const struct bdb_mipi_config *start; |
750 | const struct mipi_config *config; |
- | |
751 | const struct mipi_pps_data *pps; |
- | |
752 | u8 *data; |
- | |
753 | const u8 *seq_data; |
- | |
Line 754... | Line 705... | ||
754 | int i, panel_id, seq_size; |
705 | const struct mipi_config *config; |
755 | u16 block_size; |
706 | const struct mipi_pps_data *pps; |
756 | 707 | ||
Line 796... | Line 747... | ||
796 | return; |
747 | return; |
797 | } |
748 | } |
Line 798... | Line 749... | ||
798 | 749 | ||
799 | /* We have mandatory mipi config blocks. Initialize as generic panel */ |
750 | /* We have mandatory mipi config blocks. Initialize as generic panel */ |
- | 751 | dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; |
|
Line 800... | Line 752... | ||
800 | dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; |
752 | } |
- | 753 | ||
- | 754 | /* Find the sequence block and size for the given panel. */ |
|
- | 755 | static const u8 * |
|
- | 756 | find_panel_sequence_block(const struct bdb_mipi_sequence *sequence, |
|
- | 757 | u16 panel_id, u32 *seq_size) |
|
- | 758 | { |
|
- | 759 | u32 total = get_blocksize(sequence); |
|
- | 760 | const u8 *data = &sequence->data[0]; |
|
801 | 761 | u8 current_id; |
|
- | 762 | u32 current_size; |
|
- | 763 | int header_size = sequence->version >= 3 ? 5 : 3; |
|
- | 764 | int index = 0; |
|
- | 765 | int i; |
|
802 | /* Check if we have sequence block as well */ |
766 | |
- | 767 | /* skip new block size */ |
|
- | 768 | if (sequence->version >= 3) |
|
- | 769 | data += 4; |
|
- | 770 | ||
803 | sequence = find_section(bdb, BDB_MIPI_SEQUENCE); |
771 | for (i = 0; i < MAX_MIPI_CONFIGURATIONS && index < total; i++) { |
804 | if (!sequence) { |
772 | if (index + header_size > total) { |
805 | DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n"); |
773 | DRM_ERROR("Invalid sequence block (header)\n"); |
Line 806... | Line 774... | ||
806 | return; |
774 | return NULL; |
807 | } |
775 | } |
- | 776 | ||
- | 777 | current_id = *(data + index); |
|
- | 778 | if (sequence->version >= 3) |
|
- | 779 | current_size = *((const u32 *)(data + index + 1)); |
|
- | 780 | else |
|
- | 781 | current_size = *((const u16 *)(data + index + 1)); |
|
- | 782 | ||
808 | 783 | index += header_size; |
|
809 | /* Fail gracefully for forward incompatible sequence block. */ |
784 | |
- | 785 | if (index + current_size > total) { |
|
- | 786 | DRM_ERROR("Invalid sequence block\n"); |
|
- | 787 | return NULL; |
|
- | 788 | } |
|
- | 789 | ||
810 | if (sequence->version >= 3) { |
790 | if (current_id == panel_id) { |
Line -... | Line 791... | ||
- | 791 | *seq_size = current_size; |
|
- | 792 | return data + index; |
|
- | 793 | } |
|
811 | DRM_ERROR("Unable to parse MIPI Sequence Block v3+\n"); |
794 | |
Line -... | Line 795... | ||
- | 795 | index += current_size; |
|
- | 796 | } |
|
- | 797 | ||
- | 798 | DRM_ERROR("Sequence block detected but no valid configuration\n"); |
|
- | 799 | ||
- | 800 | return NULL; |
|
- | 801 | } |
|
- | 802 | ||
- | 803 | static int goto_next_sequence(const u8 *data, int index, int total) |
|
- | 804 | { |
|
- | 805 | u16 len; |
|
- | 806 | ||
- | 807 | /* Skip Sequence Byte. */ |
|
- | 808 | for (index = index + 1; index < total; index += len) { |
|
- | 809 | u8 operation_byte = *(data + index); |
|
- | 810 | index++; |
|
- | 811 | ||
- | 812 | switch (operation_byte) { |
|
- | 813 | case MIPI_SEQ_ELEM_END: |
|
- | 814 | return index; |
|
- | 815 | case MIPI_SEQ_ELEM_SEND_PKT: |
|
- | 816 | if (index + 4 > total) |
|
- | 817 | return 0; |
|
- | 818 | ||
- | 819 | len = *((const u16 *)(data + index + 2)) + 4; |
|
- | 820 | break; |
|
- | 821 | case MIPI_SEQ_ELEM_DELAY: |
|
- | 822 | len = 4; |
|
- | 823 | break; |
|
- | 824 | case MIPI_SEQ_ELEM_GPIO: |
|
- | 825 | len = 2; |
|
- | 826 | break; |
|
- | 827 | case MIPI_SEQ_ELEM_I2C: |
|
- | 828 | if (index + 7 > total) |
|
- | 829 | return 0; |
|
- | 830 | len = *(data + index + 6) + 7; |
|
- | 831 | break; |
|
- | 832 | default: |
|
- | 833 | DRM_ERROR("Unknown operation byte\n"); |
|
- | 834 | return 0; |
|
- | 835 | } |
|
- | 836 | } |
|
- | 837 | ||
- | 838 | return 0; |
|
- | 839 | } |
|
812 | return; |
840 | |
Line 813... | Line 841... | ||
813 | } |
841 | static int goto_next_sequence_v3(const u8 *data, int index, int total) |
814 | 842 | { |
|
- | 843 | int seq_end; |
|
815 | DRM_DEBUG_DRIVER("Found MIPI sequence block\n"); |
844 | u16 len; |
- | 845 | u32 size_of_sequence; |
|
816 | 846 | ||
- | 847 | /* |
|
- | 848 | * Could skip sequence based on Size of Sequence alone, but also do some |
|
Line 817... | Line 849... | ||
817 | block_size = get_blocksize(sequence); |
849 | * checking on the structure. |
- | 850 | */ |
|
Line 818... | Line 851... | ||
818 | 851 | if (total < 5) { |
|
819 | /* |
852 | DRM_ERROR("Too small sequence size\n"); |
820 | * parse the sequence block for individual sequences |
853 | return 0; |
- | 854 | } |
|
821 | */ |
855 | |
822 | dev_priv->vbt.dsi.seq_version = sequence->version; |
- | |
823 | - | ||
824 | seq_data = &sequence->data[0]; |
856 | /* Skip Sequence Byte. */ |
825 | - | ||
826 | /* |
857 | index++; |
Line 827... | Line -... | ||
827 | * sequence block is variable length and hence we need to parse and |
- | |
828 | * get the sequence data for specific panel id |
858 | |
829 | */ |
859 | /* |
830 | for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) { |
860 | * Size of Sequence. Excludes the Sequence Byte and the size itself, |
831 | panel_id = *seq_data; |
861 | * includes MIPI_SEQ_ELEM_END byte, excludes the final MIPI_SEQ_END |
832 | seq_size = *((u16 *) (seq_data + 1)); |
862 | * byte. |
- | 863 | */ |
|
- | 864 | size_of_sequence = *((const uint32_t *)(data + index)); |
|
- | 865 | index += 4; |
|
- | 866 | ||
- | 867 | seq_end = index + size_of_sequence; |
|
- | 868 | if (seq_end > total) { |
|
- | 869 | DRM_ERROR("Invalid sequence size\n"); |
|
- | 870 | return 0; |
|
- | 871 | } |
|
- | 872 | ||
- | 873 | for (; index < total; index += len) { |
|
833 | if (panel_id == panel_type) |
874 | u8 operation_byte = *(data + index); |
Line -... | Line 875... | ||
- | 875 | index++; |
|
- | 876 | ||
- | 877 | if (operation_byte == MIPI_SEQ_ELEM_END) { |
|
- | 878 | if (index != seq_end) { |
|
- | 879 | DRM_ERROR("Invalid element structure\n"); |
|
- | 880 | return 0; |
|
- | 881 | } |
|
- | 882 | return index; |
|
- | 883 | } |
|
- | 884 | ||
834 | break; |
885 | len = *(data + index); |
- | 886 | index++; |
|
- | 887 | ||
- | 888 | /* |
|
- | 889 | * FIXME: Would be nice to check elements like for v1/v2 in |
|
- | 890 | * goto_next_sequence() above. |
|
- | 891 | */ |
|
- | 892 | switch (operation_byte) { |
|
- | 893 | case MIPI_SEQ_ELEM_SEND_PKT: |
|
- | 894 | case MIPI_SEQ_ELEM_DELAY: |
|
- | 895 | case MIPI_SEQ_ELEM_GPIO: |
|
- | 896 | case MIPI_SEQ_ELEM_I2C: |
|
- | 897 | case MIPI_SEQ_ELEM_SPI: |
|
- | 898 | case MIPI_SEQ_ELEM_PMIC: |
|
- | 899 | break; |
|
- | 900 | default: |
|
- | 901 | DRM_ERROR("Unknown operation byte %u\n", |
|
- | 902 | operation_byte); |
|
- | 903 | break; |
|
- | 904 | } |
|
- | 905 | } |
|
- | 906 | ||
- | 907 | return 0; |
|
- | 908 | } |
|
- | 909 | ||
- | 910 | static void |
|
- | 911 | parse_mipi_sequence(struct drm_i915_private *dev_priv, |
|
- | 912 | const struct bdb_header *bdb) |
|
- | 913 | { |
|
- | 914 | const struct bdb_mipi_sequence *sequence; |
|
- | 915 | const u8 *seq_data; |
|
835 | 916 | u32 seq_size; |
|
836 | /* skip the sequence including seq header of 3 bytes */ |
917 | u8 *data; |
837 | seq_data = seq_data + 3 + seq_size; |
918 | int index = 0; |
Line 838... | Line 919... | ||
838 | if ((seq_data - &sequence->data[0]) > block_size) { |
919 | |
839 | DRM_ERROR("Sequence start is beyond sequence block size, corrupted sequence block\n"); |
920 | /* Only our generic panel driver uses the sequence block. */ |
840 | return; |
921 | if (dev_priv->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) |
841 | } |
922 | return; |
842 | } |
923 | |
843 | 924 | sequence = find_section(bdb, BDB_MIPI_SEQUENCE); |
|
Line 844... | Line 925... | ||
844 | if (i == MAX_MIPI_CONFIGURATIONS) { |
925 | if (!sequence) { |
- | 926 | DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n"); |
|
845 | DRM_ERROR("Sequence block detected but no valid configuration\n"); |
927 | return; |
846 | return; |
928 | } |
847 | } |
929 | |
Line 848... | Line -... | ||
848 | - | ||
849 | /* check if found sequence is completely within the sequence block |
- | |
850 | * just being paranoid */ |
930 | /* Fail gracefully for forward incompatible sequence block. */ |
851 | if (seq_size > block_size) { |
931 | if (sequence->version >= 4) { |
852 | DRM_ERROR("Corrupted sequence/size, bailing out\n"); |
932 | DRM_ERROR("Unable to parse MIPI Sequence Block v%u\n", |
853 | return; |
- | |
Line 854... | Line 933... | ||
854 | } |
933 | sequence->version); |
855 | 934 | return; |
|
856 | /* skip the panel id(1 byte) and seq size(2 bytes) */ |
935 | } |
857 | dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size, GFP_KERNEL); |
936 | |
858 | if (!dev_priv->vbt.dsi.data) |
- | |
859 | return; |
- | |
860 | 937 | DRM_DEBUG_DRIVER("Found MIPI sequence block v%u\n", sequence->version); |
|
- | 938 | ||
- | 939 | seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size); |
|
861 | /* |
940 | if (!seq_data) |
862 | * loop into the sequence data and split into multiple sequneces |
941 | return; |
863 | * There are only 5 types of sequences as of now |
942 | |
Line 864... | Line -... | ||
864 | */ |
- | |
865 | data = dev_priv->vbt.dsi.data; |
943 | data = kmemdup(seq_data, seq_size, GFP_KERNEL); |
Line -... | Line 944... | ||
- | 944 | if (!data) |
|
- | 945 | return; |
|
- | 946 | ||
- | 947 | /* Parse the sequences, store pointers to each sequence. */ |
|
866 | dev_priv->vbt.dsi.size = seq_size; |
948 | for (;;) { |
867 | 949 | u8 seq_id = *(data + index); |
|
868 | /* two consecutive 0x00 indicate end of all sequences */ |
950 | if (seq_id == MIPI_SEQ_END) |
869 | while (1) { |
951 | break; |
870 | int seq_id = *data; |
- | |
871 | if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED) { |
- | |
872 | dev_priv->vbt.dsi.sequence[seq_id] = data; |
- | |
873 | DRM_DEBUG_DRIVER("Found mipi sequence - %d\n", seq_id); |
952 | |
Line -... | Line 953... | ||
- | 953 | if (seq_id >= MIPI_SEQ_MAX) { |
|
- | 954 | DRM_ERROR("Unknown sequence %u\n", seq_id); |
|
- | 955 | goto err; |
|
- | 956 | } |
|
874 | } else { |
957 | |
875 | DRM_ERROR("undefined sequence\n"); |
958 | dev_priv->vbt.dsi.sequence[seq_id] = data + index; |
876 | goto err; |
- | |
877 | } |
- | |
878 | - | ||
Line 879... | Line -... | ||
879 | /* partial parsing to skip elements */ |
- | |
- | 959 | ||
880 | data = goto_next_sequence(data, &seq_size); |
960 | if (sequence->version >= 3) |
881 | 961 | index = goto_next_sequence_v3(data, index, seq_size); |
|
882 | if (data == NULL) { |
962 | else |
Line 883... | Line 963... | ||
883 | DRM_ERROR("Sequence elements going beyond block itself. Sequence block parsing failed\n"); |
963 | index = goto_next_sequence(data, index, seq_size); |
884 | goto err; |
964 | if (!index) { |
Line 1086... | Line 1166... | ||
1086 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
1166 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
1087 | if (!p_defs) { |
1167 | if (!p_defs) { |
1088 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
1168 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
1089 | return; |
1169 | return; |
1090 | } |
1170 | } |
1091 | if (bdb->version < 195) { |
1171 | if (bdb->version < 106) { |
- | 1172 | expected_size = 22; |
|
- | 1173 | } else if (bdb->version < 109) { |
|
- | 1174 | expected_size = 27; |
|
- | 1175 | } else if (bdb->version < 195) { |
|
- | 1176 | BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); |
|
1092 | expected_size = sizeof(struct old_child_dev_config); |
1177 | expected_size = sizeof(struct old_child_dev_config); |
1093 | } else if (bdb->version == 195) { |
1178 | } else if (bdb->version == 195) { |
1094 | expected_size = 37; |
1179 | expected_size = 37; |
1095 | } else if (bdb->version <= 197) { |
1180 | } else if (bdb->version <= 197) { |
1096 | expected_size = 38; |
1181 | expected_size = 38; |
Line 1099... | Line 1184... | ||
1099 | BUILD_BUG_ON(sizeof(*p_child) < 38); |
1184 | BUILD_BUG_ON(sizeof(*p_child) < 38); |
1100 | DRM_DEBUG_DRIVER("Expected child device config size for VBT version %u not known; assuming %u\n", |
1185 | DRM_DEBUG_DRIVER("Expected child device config size for VBT version %u not known; assuming %u\n", |
1101 | bdb->version, expected_size); |
1186 | bdb->version, expected_size); |
1102 | } |
1187 | } |
Line -... | Line 1188... | ||
- | 1188 | ||
- | 1189 | /* Flag an error for unexpected size, but continue anyway. */ |
|
- | 1190 | if (p_defs->child_dev_size != expected_size) |
|
- | 1191 | DRM_ERROR("Unexpected child device config size %u (expected %u for VBT version %u)\n", |
|
- | 1192 | p_defs->child_dev_size, expected_size, bdb->version); |
|
1103 | 1193 | ||
1104 | /* The legacy sized child device config is the minimum we need. */ |
1194 | /* The legacy sized child device config is the minimum we need. */ |
1105 | if (p_defs->child_dev_size < sizeof(struct old_child_dev_config)) { |
1195 | if (p_defs->child_dev_size < sizeof(struct old_child_dev_config)) { |
1106 | DRM_ERROR("Child device config size %u is too small.\n", |
1196 | DRM_DEBUG_KMS("Child device config size %u is too small.\n", |
1107 | p_defs->child_dev_size); |
1197 | p_defs->child_dev_size); |
1108 | return; |
1198 | return; |
Line 1109... | Line -... | ||
1109 | } |
- | |
1110 | - | ||
1111 | /* Flag an error for unexpected size, but continue anyway. */ |
- | |
1112 | if (p_defs->child_dev_size != expected_size) |
- | |
1113 | DRM_ERROR("Unexpected child device config size %u (expected %u for VBT version %u)\n", |
- | |
1114 | p_defs->child_dev_size, expected_size, bdb->version); |
1199 | } |
1115 | 1200 | ||
1116 | /* get the block size of general definitions */ |
1201 | /* get the block size of general definitions */ |
1117 | block_size = get_blocksize(p_defs); |
1202 | block_size = get_blocksize(p_defs); |
1118 | /* get the number of child device */ |
1203 | /* get the number of child device */ |
Line 1283... | Line 1368... | ||
1283 | return NULL; |
1368 | return NULL; |
1284 | } |
1369 | } |
Line 1285... | Line 1370... | ||
1285 | 1370 | ||
1286 | /** |
1371 | /** |
1287 | * intel_bios_init - find VBT and initialize settings from the BIOS |
1372 | * intel_bios_init - find VBT and initialize settings from the BIOS |
1288 | * @dev: DRM device |
1373 | * @dev_priv: i915 device instance |
1289 | * |
1374 | * |
1290 | * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers |
1375 | * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers |
1291 | * to appropriate values. |
1376 | * to appropriate values. |
1292 | * |
1377 | * |
Line 1335... | Line 1420... | ||
1335 | parse_sdvo_device_mapping(dev_priv, bdb); |
1420 | parse_sdvo_device_mapping(dev_priv, bdb); |
1336 | parse_device_mapping(dev_priv, bdb); |
1421 | parse_device_mapping(dev_priv, bdb); |
1337 | parse_driver_features(dev_priv, bdb); |
1422 | parse_driver_features(dev_priv, bdb); |
1338 | parse_edp(dev_priv, bdb); |
1423 | parse_edp(dev_priv, bdb); |
1339 | parse_psr(dev_priv, bdb); |
1424 | parse_psr(dev_priv, bdb); |
1340 | parse_mipi(dev_priv, bdb); |
1425 | parse_mipi_config(dev_priv, bdb); |
- | 1426 | parse_mipi_sequence(dev_priv, bdb); |
|
1341 | parse_ddi_ports(dev_priv, bdb); |
1427 | parse_ddi_ports(dev_priv, bdb); |
Line 1342... | Line 1428... | ||
1342 | 1428 | ||
1343 | if (bios) |
1429 | if (bios) |