Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/bridge: refactor HDMI InfoFrame callbacks

Having only a single set of callbacks, hdmi_clear_infoframe and
hdmi_write_infoframe, bridge drivers don't have an easy way to signal to
the DRM framework, which InfoFrames are actually supported by the
hardware and by the driver and which are not. Also, it makes it
extremely easy for HDMI bridge drivers to skip implementing the
seemingly required InfoFrames (e.g. HDMI VSI). Last, but not least,
those callbacks take a single 'type' parameter, which makes it
impossible to implement support for multiple VSIs (which will be
required once we start working on HDMI Forum VSI).

Split the callbacks into a per-InfoFrame-kind pairs, letting the bridge
drivers actually signal supported features. The implementation follows
the overall drm_bridge design, where the bridge has a single
drm_bridge_funcs implementation and signals, which functions are to be
called using the drm_bridge->ops flags.

The AVI and HDMI VSI are assumed to be required for a normal HDMI
operation (with the drivers getting a drm_warn_once() stub
implementation if one is missing). The Audio InfoFrame is handled by the
existing DRM_BRIDGE_OP_HDMI_AUDIO, while the SPD and HDR DRM InfoFrames
got new drm_bridge_ops values.

Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://patch.msgid.link/20260107-limit-infoframes-2-v4-5-213d0d3bd490@oss.qualcomm.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

+698 -414
+98 -68
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
··· 887 887 return adv7511_edid_read(adv, connector); 888 888 } 889 889 890 - static int adv7511_bridge_hdmi_clear_infoframe(struct drm_bridge *bridge, 891 - enum hdmi_infoframe_type type) 890 + static int adv7511_bridge_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) 892 891 { 893 892 struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 894 893 895 - switch (type) { 896 - case HDMI_INFOFRAME_TYPE_AUDIO: 897 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 898 - break; 899 - case HDMI_INFOFRAME_TYPE_AVI: 900 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 901 - break; 902 - case HDMI_INFOFRAME_TYPE_SPD: 903 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 904 - break; 905 - case HDMI_INFOFRAME_TYPE_VENDOR: 906 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 907 - break; 908 - default: 909 - drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 910 - break; 911 - } 894 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 912 895 913 896 return 0; 914 897 } 915 898 916 - static int adv7511_bridge_hdmi_write_infoframe(struct drm_bridge *bridge, 917 - enum hdmi_infoframe_type type, 918 - const u8 *buffer, size_t len) 899 + static int adv7511_bridge_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 919 900 { 920 901 struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 921 902 922 - switch (type) { 923 - case HDMI_INFOFRAME_TYPE_AUDIO: 924 - /* send current Audio infoframe values while updating */ 925 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 926 - BIT(5), BIT(5)); 903 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 927 904 928 - /* The Audio infoframe id is not configurable */ 929 - regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, 930 - buffer + 1, len - 1); 905 + return 0; 906 + } 931 907 932 - /* use Audio infoframe updated info */ 933 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 934 - BIT(5), 0); 908 + static int adv7511_bridge_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) 909 + { 910 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 935 911 936 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 937 - break; 938 - case HDMI_INFOFRAME_TYPE_AVI: 939 - /* send current AVI infoframe values while updating */ 940 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 941 - BIT(6), BIT(6)); 912 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 942 913 943 - /* The AVI infoframe id is not configurable */ 944 - regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, 945 - buffer + 1, len - 1); 914 + return 0; 915 + } 946 916 947 - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); 948 - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); 917 + static int adv7511_bridge_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 918 + { 919 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 949 920 950 - /* use AVI infoframe updated info */ 951 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 952 - BIT(6), 0); 921 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 953 922 954 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 955 - break; 956 - case HDMI_INFOFRAME_TYPE_SPD: 957 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 958 - regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), 959 - buffer, len); 960 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); 961 - break; 962 - case HDMI_INFOFRAME_TYPE_VENDOR: 963 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 964 - regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), 965 - buffer, len); 966 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 967 - break; 968 - default: 969 - drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 970 - break; 971 - } 923 + return 0; 924 + } 925 + 926 + static int adv7511_bridge_hdmi_write_audio_infoframe(struct drm_bridge *bridge, 927 + const u8 *buffer, size_t len) 928 + { 929 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 930 + 931 + /* send current Audio infoframe values while updating */ 932 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 933 + BIT(5), BIT(5)); 934 + 935 + /* The Audio infoframe id is not configurable */ 936 + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, 937 + buffer + 1, len - 1); 938 + 939 + /* use Audio infoframe updated info */ 940 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 941 + BIT(5), 0); 942 + 943 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 944 + 945 + return 0; 946 + } 947 + 948 + static int adv7511_bridge_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 949 + const u8 *buffer, size_t len) 950 + { 951 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 952 + 953 + /* send current AVI infoframe values while updating */ 954 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 955 + BIT(6), BIT(6)); 956 + 957 + /* The AVI infoframe id is not configurable */ 958 + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, 959 + buffer + 1, len - 1); 960 + 961 + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); 962 + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); 963 + 964 + /* use AVI infoframe updated info */ 965 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 966 + BIT(6), 0); 967 + 968 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 969 + 970 + return 0; 971 + } 972 + 973 + static int adv7511_bridge_hdmi_write_spd_infoframe(struct drm_bridge *bridge, 974 + const u8 *buffer, size_t len) 975 + { 976 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 977 + 978 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 979 + regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), 980 + buffer, len); 981 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); 982 + 983 + return 0; 984 + } 985 + 986 + static int adv7511_bridge_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 987 + const u8 *buffer, size_t len) 988 + { 989 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 990 + 991 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 992 + regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), 993 + buffer, len); 994 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 972 995 973 996 return 0; 974 997 } ··· 1009 986 .atomic_reset = drm_atomic_helper_bridge_reset, 1010 987 1011 988 .hdmi_tmds_char_rate_valid = adv7511_bridge_hdmi_tmds_char_rate_valid, 1012 - .hdmi_clear_infoframe = adv7511_bridge_hdmi_clear_infoframe, 1013 - .hdmi_write_infoframe = adv7511_bridge_hdmi_write_infoframe, 989 + .hdmi_clear_audio_infoframe = adv7511_bridge_hdmi_clear_audio_infoframe, 990 + .hdmi_write_audio_infoframe = adv7511_bridge_hdmi_write_audio_infoframe, 991 + .hdmi_clear_avi_infoframe = adv7511_bridge_hdmi_clear_avi_infoframe, 992 + .hdmi_write_avi_infoframe = adv7511_bridge_hdmi_write_avi_infoframe, 993 + .hdmi_clear_spd_infoframe = adv7511_bridge_hdmi_clear_spd_infoframe, 994 + .hdmi_write_spd_infoframe = adv7511_bridge_hdmi_write_spd_infoframe, 995 + .hdmi_clear_hdmi_infoframe = adv7511_bridge_hdmi_clear_hdmi_infoframe, 996 + .hdmi_write_hdmi_infoframe = adv7511_bridge_hdmi_write_hdmi_infoframe, 1014 997 1015 998 .hdmi_audio_startup = adv7511_hdmi_audio_startup, 1016 999 .hdmi_audio_prepare = adv7511_hdmi_audio_prepare, ··· 1351 1322 1352 1323 adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | 1353 1324 DRM_BRIDGE_OP_EDID | 1354 - DRM_BRIDGE_OP_HDMI; 1325 + DRM_BRIDGE_OP_HDMI | 1326 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; 1355 1327 if (adv7511->i2c_main->irq) 1356 1328 adv7511->bridge.ops |= DRM_BRIDGE_OP_HPD; 1357 1329
+23 -18
drivers/gpu/drm/bridge/inno-hdmi.c
··· 584 584 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1)); 585 585 } 586 586 587 - static int inno_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, 588 - enum hdmi_infoframe_type type) 587 + static int inno_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 589 588 { 590 589 struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge); 591 - 592 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 593 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 594 - return 0; 595 - } 596 590 597 591 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); 598 592 599 593 return 0; 600 594 } 601 595 602 - static int inno_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, 603 - enum hdmi_infoframe_type type, 604 - const u8 *buffer, size_t len) 596 + static int inno_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, 597 + const u8 *buffer, size_t len) 605 598 { 606 599 struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge); 607 600 ssize_t i; 608 601 609 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 610 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 611 - return 0; 612 - } 613 - 614 - inno_hdmi_bridge_clear_infoframe(bridge, type); 602 + inno_hdmi_bridge_clear_avi_infoframe(bridge); 615 603 616 604 for (i = 0; i < len; i++) 617 605 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, buffer[i]); 606 + 607 + return 0; 608 + } 609 + 610 + static int inno_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 611 + { 612 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not implemented\n"); 613 + 614 + return 0; 615 + } 616 + 617 + static int inno_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 618 + const u8 *buffer, size_t len) 619 + { 620 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not implemented\n"); 618 621 619 622 return 0; 620 623 } ··· 886 883 .atomic_disable = inno_hdmi_bridge_atomic_disable, 887 884 .detect = inno_hdmi_bridge_detect, 888 885 .edid_read = inno_hdmi_bridge_edid_read, 889 - .hdmi_clear_infoframe = inno_hdmi_bridge_clear_infoframe, 890 - .hdmi_write_infoframe = inno_hdmi_bridge_write_infoframe, 886 + .hdmi_clear_avi_infoframe = inno_hdmi_bridge_clear_avi_infoframe, 887 + .hdmi_write_avi_infoframe = inno_hdmi_bridge_write_avi_infoframe, 888 + .hdmi_clear_hdmi_infoframe = inno_hdmi_bridge_clear_hdmi_infoframe, 889 + .hdmi_write_hdmi_infoframe = inno_hdmi_bridge_write_hdmi_infoframe, 891 890 .mode_valid = inno_hdmi_bridge_mode_valid, 892 891 }; 893 892
+45 -42
drivers/gpu/drm/bridge/ite-it6263.c
··· 759 759 return MODE_OK; 760 760 } 761 761 762 - static int it6263_hdmi_clear_infoframe(struct drm_bridge *bridge, 763 - enum hdmi_infoframe_type type) 762 + static int it6263_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 764 763 { 765 764 struct it6263 *it = bridge_to_it6263(bridge); 766 765 767 - switch (type) { 768 - case HDMI_INFOFRAME_TYPE_AVI: 769 - regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); 770 - break; 771 - case HDMI_INFOFRAME_TYPE_VENDOR: 772 - regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); 773 - break; 774 - default: 775 - dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); 776 - } 766 + regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); 777 767 778 768 return 0; 779 769 } 780 770 781 - static int it6263_hdmi_write_infoframe(struct drm_bridge *bridge, 782 - enum hdmi_infoframe_type type, 783 - const u8 *buffer, size_t len) 771 + static int it6263_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 772 + { 773 + struct it6263 *it = bridge_to_it6263(bridge); 774 + 775 + regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); 776 + 777 + return 0; 778 + } 779 + 780 + static int it6263_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 781 + const u8 *buffer, size_t len) 784 782 { 785 783 struct it6263 *it = bridge_to_it6263(bridge); 786 784 struct regmap *regmap = it->hdmi_regmap; 787 785 788 - switch (type) { 789 - case HDMI_INFOFRAME_TYPE_AVI: 790 - /* write the first AVI infoframe data byte chunk(DB1-DB5) */ 791 - regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, 792 - &buffer[HDMI_INFOFRAME_HEADER_SIZE], 793 - HDMI_AVI_DB_CHUNK1_SIZE); 786 + /* write the first AVI infoframe data byte chunk(DB1-DB5) */ 787 + regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, 788 + &buffer[HDMI_INFOFRAME_HEADER_SIZE], 789 + HDMI_AVI_DB_CHUNK1_SIZE); 794 790 795 - /* write the second AVI infoframe data byte chunk(DB6-DB13) */ 796 - regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, 797 - &buffer[HDMI_INFOFRAME_HEADER_SIZE + 798 - HDMI_AVI_DB_CHUNK1_SIZE], 799 - HDMI_AVI_DB_CHUNK2_SIZE); 791 + /* write the second AVI infoframe data byte chunk(DB6-DB13) */ 792 + regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, 793 + &buffer[HDMI_INFOFRAME_HEADER_SIZE + 794 + HDMI_AVI_DB_CHUNK1_SIZE], 795 + HDMI_AVI_DB_CHUNK2_SIZE); 800 796 801 - /* write checksum */ 802 - regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); 797 + /* write checksum */ 798 + regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); 803 799 804 - regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, 805 - ENABLE_PKT | REPEAT_PKT); 806 - break; 807 - case HDMI_INFOFRAME_TYPE_VENDOR: 808 - /* write header and payload */ 809 - regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); 800 + regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, 801 + ENABLE_PKT | REPEAT_PKT); 810 802 811 - regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, 812 - ENABLE_PKT | REPEAT_PKT); 813 - break; 814 - default: 815 - dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); 816 - } 803 + return 0; 804 + } 805 + 806 + static int it6263_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 807 + const u8 *buffer, size_t len) 808 + { 809 + struct it6263 *it = bridge_to_it6263(bridge); 810 + struct regmap *regmap = it->hdmi_regmap; 811 + 812 + /* write header and payload */ 813 + regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); 814 + 815 + regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, 816 + ENABLE_PKT | REPEAT_PKT); 817 + 817 818 818 819 return 0; 819 820 } ··· 831 830 .edid_read = it6263_bridge_edid_read, 832 831 .atomic_get_input_bus_fmts = it6263_bridge_atomic_get_input_bus_fmts, 833 832 .hdmi_tmds_char_rate_valid = it6263_hdmi_tmds_char_rate_valid, 834 - .hdmi_clear_infoframe = it6263_hdmi_clear_infoframe, 835 - .hdmi_write_infoframe = it6263_hdmi_write_infoframe, 833 + .hdmi_clear_avi_infoframe = it6263_hdmi_clear_avi_infoframe, 834 + .hdmi_write_avi_infoframe = it6263_hdmi_write_avi_infoframe, 835 + .hdmi_clear_hdmi_infoframe = it6263_hdmi_clear_hdmi_infoframe, 836 + .hdmi_write_hdmi_infoframe = it6263_hdmi_write_hdmi_infoframe, 836 837 }; 837 838 838 839 static int it6263_probe(struct i2c_client *client)
+82 -63
drivers/gpu/drm/bridge/lontium-lt9611.c
··· 843 843 #define LT9611_INFOFRAME_AUDIO 0x02 844 844 #define LT9611_INFOFRAME_AVI 0x08 845 845 #define LT9611_INFOFRAME_SPD 0x10 846 - #define LT9611_INFOFRAME_VENDOR 0x20 846 + #define LT9611_INFOFRAME_HDMI 0x20 847 847 848 - static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge, 849 - enum hdmi_infoframe_type type) 848 + static int lt9611_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) 850 849 { 851 850 struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 852 - unsigned int mask; 853 851 854 - switch (type) { 855 - case HDMI_INFOFRAME_TYPE_AUDIO: 856 - mask = LT9611_INFOFRAME_AUDIO; 857 - break; 858 - 859 - case HDMI_INFOFRAME_TYPE_AVI: 860 - mask = LT9611_INFOFRAME_AVI; 861 - break; 862 - 863 - case HDMI_INFOFRAME_TYPE_SPD: 864 - mask = LT9611_INFOFRAME_SPD; 865 - break; 866 - 867 - case HDMI_INFOFRAME_TYPE_VENDOR: 868 - mask = LT9611_INFOFRAME_VENDOR; 869 - break; 870 - 871 - default: 872 - drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 873 - mask = 0; 874 - break; 875 - } 876 - 877 - if (mask) 878 - regmap_update_bits(lt9611->regmap, 0x843d, mask, 0); 852 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0); 879 853 880 854 return 0; 881 855 } 882 856 883 - static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge, 884 - enum hdmi_infoframe_type type, 885 - const u8 *buffer, size_t len) 857 + static int lt9611_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 886 858 { 887 859 struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 888 - unsigned int mask, addr; 860 + 861 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, 0); 862 + 863 + return 0; 864 + } 865 + 866 + static int lt9611_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) 867 + { 868 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 869 + 870 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, 0); 871 + 872 + return 0; 873 + } 874 + 875 + static int lt9611_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 876 + { 877 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 878 + 879 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, 0); 880 + 881 + return 0; 882 + } 883 + 884 + static int lt9611_hdmi_write_audio_infoframe(struct drm_bridge *bridge, 885 + const u8 *buffer, size_t len) 886 + { 887 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 889 888 int i; 890 889 891 - switch (type) { 892 - case HDMI_INFOFRAME_TYPE_AUDIO: 893 - mask = LT9611_INFOFRAME_AUDIO; 894 - addr = 0x84b2; 895 - break; 890 + for (i = 0; i < len; i++) 891 + regmap_write(lt9611->regmap, 0x84b2 + i, buffer[i]); 896 892 897 - case HDMI_INFOFRAME_TYPE_AVI: 898 - mask = LT9611_INFOFRAME_AVI; 899 - addr = 0x8440; 900 - break; 893 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, LT9611_INFOFRAME_AUDIO); 901 894 902 - case HDMI_INFOFRAME_TYPE_SPD: 903 - mask = LT9611_INFOFRAME_SPD; 904 - addr = 0x8493; 905 - break; 895 + return 0; 896 + } 906 897 907 - case HDMI_INFOFRAME_TYPE_VENDOR: 908 - mask = LT9611_INFOFRAME_VENDOR; 909 - addr = 0x8474; 910 - break; 898 + static int lt9611_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 899 + const u8 *buffer, size_t len) 900 + { 901 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 902 + int i; 911 903 912 - default: 913 - drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 914 - mask = 0; 915 - break; 916 - } 904 + for (i = 0; i < len; i++) 905 + regmap_write(lt9611->regmap, 0x8440 + i, buffer[i]); 917 906 918 - if (mask) { 919 - for (i = 0; i < len; i++) 920 - regmap_write(lt9611->regmap, addr + i, buffer[i]); 907 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, LT9611_INFOFRAME_AVI); 921 908 922 - regmap_update_bits(lt9611->regmap, 0x843d, mask, mask); 923 - } 909 + return 0; 910 + } 911 + 912 + static int lt9611_hdmi_write_spd_infoframe(struct drm_bridge *bridge, 913 + const u8 *buffer, size_t len) 914 + { 915 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 916 + int i; 917 + 918 + for (i = 0; i < len; i++) 919 + regmap_write(lt9611->regmap, 0x8493 + i, buffer[i]); 920 + 921 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, LT9611_INFOFRAME_SPD); 922 + 923 + return 0; 924 + } 925 + 926 + static int lt9611_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 927 + const u8 *buffer, size_t len) 928 + { 929 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 930 + int i; 931 + 932 + for (i = 0; i < len; i++) 933 + regmap_write(lt9611->regmap, 0x8474 + i, buffer[i]); 934 + 935 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, LT9611_INFOFRAME_HDMI); 924 936 925 937 return 0; 926 938 } ··· 1015 1003 .atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts, 1016 1004 1017 1005 .hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid, 1018 - .hdmi_write_infoframe = lt9611_hdmi_write_infoframe, 1019 - .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe, 1006 + .hdmi_write_audio_infoframe = lt9611_hdmi_write_audio_infoframe, 1007 + .hdmi_clear_audio_infoframe = lt9611_hdmi_clear_audio_infoframe, 1008 + .hdmi_write_avi_infoframe = lt9611_hdmi_write_avi_infoframe, 1009 + .hdmi_clear_avi_infoframe = lt9611_hdmi_clear_avi_infoframe, 1010 + .hdmi_write_spd_infoframe = lt9611_hdmi_write_spd_infoframe, 1011 + .hdmi_clear_spd_infoframe = lt9611_hdmi_clear_spd_infoframe, 1012 + .hdmi_write_hdmi_infoframe = lt9611_hdmi_write_hdmi_infoframe, 1013 + .hdmi_clear_hdmi_infoframe = lt9611_hdmi_clear_hdmi_infoframe, 1020 1014 1021 1015 .hdmi_audio_startup = lt9611_hdmi_audio_startup, 1022 1016 .hdmi_audio_prepare = lt9611_hdmi_audio_prepare, ··· 1150 1132 lt9611->bridge.of_node = client->dev.of_node; 1151 1133 lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | 1152 1134 DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES | 1153 - DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO; 1135 + DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO | 1136 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; 1154 1137 lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 1155 1138 lt9611->bridge.vendor = "Lontium"; 1156 1139 lt9611->bridge.product = "LT9611";
+76 -40
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 26 26 #include <drm/drm_connector.h> 27 27 #include <drm/drm_edid.h> 28 28 #include <drm/drm_modes.h> 29 + #include <drm/drm_print.h> 29 30 30 31 #include <media/cec.h> 31 32 ··· 957 956 return MODE_OK; 958 957 } 959 958 960 - static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge, 961 - enum hdmi_infoframe_type type) 959 + static int dw_hdmi_qp_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 962 960 { 963 961 struct dw_hdmi_qp *hdmi = bridge->driver_private; 964 962 965 - switch (type) { 966 - case HDMI_INFOFRAME_TYPE_AVI: 967 - dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, 968 - PKTSCHED_PKT_EN); 969 - break; 970 - 971 - case HDMI_INFOFRAME_TYPE_DRM: 972 - dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); 973 - break; 974 - 975 - case HDMI_INFOFRAME_TYPE_AUDIO: 976 - dw_hdmi_qp_mod(hdmi, 0, 977 - PKTSCHED_ACR_TX_EN | 978 - PKTSCHED_AUDS_TX_EN | 979 - PKTSCHED_AUDI_TX_EN, 980 - PKTSCHED_PKT_EN); 981 - break; 982 - default: 983 - dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); 984 - } 963 + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, 964 + PKTSCHED_PKT_EN); 985 965 986 966 return 0; 987 967 } 988 968 989 - static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge, 990 - enum hdmi_infoframe_type type, 991 - const u8 *buffer, size_t len) 969 + static int dw_hdmi_qp_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 970 + { 971 + /* FIXME: add support for this InfoFrame */ 972 + 973 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n"); 974 + 975 + return 0; 976 + } 977 + 978 + static int dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(struct drm_bridge *bridge) 992 979 { 993 980 struct dw_hdmi_qp *hdmi = bridge->driver_private; 994 981 995 - dw_hdmi_qp_bridge_clear_infoframe(bridge, type); 982 + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); 996 983 997 - switch (type) { 998 - case HDMI_INFOFRAME_TYPE_AVI: 999 - return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); 984 + return 0; 985 + } 1000 986 1001 - case HDMI_INFOFRAME_TYPE_DRM: 1002 - return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); 987 + static int dw_hdmi_qp_bridge_clear_audio_infoframe(struct drm_bridge *bridge) 988 + { 989 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1003 990 1004 - case HDMI_INFOFRAME_TYPE_AUDIO: 1005 - return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len); 991 + dw_hdmi_qp_mod(hdmi, 0, 992 + PKTSCHED_ACR_TX_EN | 993 + PKTSCHED_AUDS_TX_EN | 994 + PKTSCHED_AUDI_TX_EN, 995 + PKTSCHED_PKT_EN); 1006 996 1007 - default: 1008 - dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); 1009 - return 0; 1010 - } 997 + return 0; 998 + } 999 + 1000 + static int dw_hdmi_qp_bridge_write_avi_infoframe(struct drm_bridge *bridge, 1001 + const u8 *buffer, size_t len) 1002 + { 1003 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1004 + 1005 + dw_hdmi_qp_bridge_clear_avi_infoframe(bridge); 1006 + 1007 + return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); 1008 + } 1009 + 1010 + static int dw_hdmi_qp_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 1011 + const u8 *buffer, size_t len) 1012 + { 1013 + dw_hdmi_qp_bridge_clear_hdmi_infoframe(bridge); 1014 + 1015 + /* FIXME: add support for the HDMI VSI */ 1016 + 1017 + return 0; 1018 + } 1019 + 1020 + static int dw_hdmi_qp_bridge_write_hdr_drm_infoframe(struct drm_bridge *bridge, 1021 + const u8 *buffer, size_t len) 1022 + { 1023 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1024 + 1025 + dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(bridge); 1026 + 1027 + return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); 1028 + } 1029 + 1030 + static int dw_hdmi_qp_bridge_write_audio_infoframe(struct drm_bridge *bridge, 1031 + const u8 *buffer, size_t len) 1032 + { 1033 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1034 + 1035 + dw_hdmi_qp_bridge_clear_audio_infoframe(bridge); 1036 + 1037 + return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len); 1011 1038 } 1012 1039 1013 1040 #ifdef CONFIG_DRM_DW_HDMI_QP_CEC ··· 1220 1191 .detect = dw_hdmi_qp_bridge_detect, 1221 1192 .edid_read = dw_hdmi_qp_bridge_edid_read, 1222 1193 .hdmi_tmds_char_rate_valid = dw_hdmi_qp_bridge_tmds_char_rate_valid, 1223 - .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, 1224 - .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, 1194 + .hdmi_clear_avi_infoframe = dw_hdmi_qp_bridge_clear_avi_infoframe, 1195 + .hdmi_write_avi_infoframe = dw_hdmi_qp_bridge_write_avi_infoframe, 1196 + .hdmi_clear_hdmi_infoframe = dw_hdmi_qp_bridge_clear_hdmi_infoframe, 1197 + .hdmi_write_hdmi_infoframe = dw_hdmi_qp_bridge_write_hdmi_infoframe, 1198 + .hdmi_clear_hdr_drm_infoframe = dw_hdmi_qp_bridge_clear_hdr_drm_infoframe, 1199 + .hdmi_write_hdr_drm_infoframe = dw_hdmi_qp_bridge_write_hdr_drm_infoframe, 1200 + .hdmi_clear_audio_infoframe = dw_hdmi_qp_bridge_clear_audio_infoframe, 1201 + .hdmi_write_audio_infoframe = dw_hdmi_qp_bridge_write_audio_infoframe, 1225 1202 .hdmi_audio_startup = dw_hdmi_qp_audio_enable, 1226 1203 .hdmi_audio_shutdown = dw_hdmi_qp_audio_disable, 1227 1204 .hdmi_audio_prepare = dw_hdmi_qp_audio_prepare, ··· 1341 1306 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | 1342 1307 DRM_BRIDGE_OP_EDID | 1343 1308 DRM_BRIDGE_OP_HDMI | 1344 - DRM_BRIDGE_OP_HDMI_AUDIO; 1309 + DRM_BRIDGE_OP_HDMI_AUDIO | 1310 + DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME; 1345 1311 if (!hdmi->no_hpd) 1346 1312 hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD; 1347 1313 hdmi->bridge.of_node = pdev->dev.of_node;
+65 -5
drivers/gpu/drm/display/drm_bridge_connector.c
··· 412 412 if (!bridge) 413 413 return -EINVAL; 414 414 415 - return bridge->funcs->hdmi_clear_infoframe(bridge, type); 415 + switch (type) { 416 + case HDMI_INFOFRAME_TYPE_AVI: 417 + /* required */ 418 + return bridge->funcs->hdmi_clear_avi_infoframe(bridge); 419 + case HDMI_INFOFRAME_TYPE_VENDOR: 420 + /* required */ 421 + return bridge->funcs->hdmi_clear_hdmi_infoframe(bridge); 422 + case HDMI_INFOFRAME_TYPE_AUDIO: 423 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) 424 + return bridge->funcs->hdmi_clear_audio_infoframe(bridge); 425 + break; 426 + case HDMI_INFOFRAME_TYPE_DRM: 427 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) 428 + return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); 429 + break; 430 + case HDMI_INFOFRAME_TYPE_SPD: 431 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) 432 + return bridge->funcs->hdmi_clear_spd_infoframe(bridge); 433 + break; 434 + } 435 + 436 + drm_dbg_driver(connector->dev, "Unsupported HDMI InfoFrame %x\n", type); 437 + 438 + return 0; 416 439 } 417 440 418 441 static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, ··· 450 427 if (!bridge) 451 428 return -EINVAL; 452 429 453 - return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); 430 + switch (type) { 431 + case HDMI_INFOFRAME_TYPE_AVI: 432 + /* required */ 433 + return bridge->funcs->hdmi_write_avi_infoframe(bridge, buffer, len); 434 + case HDMI_INFOFRAME_TYPE_VENDOR: 435 + /* required */ 436 + return bridge->funcs->hdmi_write_hdmi_infoframe(bridge, buffer, len); 437 + case HDMI_INFOFRAME_TYPE_AUDIO: 438 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) 439 + return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); 440 + break; 441 + case HDMI_INFOFRAME_TYPE_DRM: 442 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) 443 + return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); 444 + break; 445 + case HDMI_INFOFRAME_TYPE_SPD: 446 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) 447 + return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); 448 + break; 449 + } 450 + 451 + drm_dbg_driver(connector->dev, "Unsupported HDMI InfoFrame %x\n", type); 452 + 453 + return 0; 454 454 } 455 455 456 456 static const struct drm_edid * ··· 755 709 if (bridge->ops & DRM_BRIDGE_OP_HDMI) { 756 710 if (bridge_connector->bridge_hdmi) 757 711 return ERR_PTR(-EBUSY); 758 - if (!bridge->funcs->hdmi_write_infoframe || 759 - !bridge->funcs->hdmi_clear_infoframe) 712 + if (!bridge->funcs->hdmi_write_avi_infoframe || 713 + !bridge->funcs->hdmi_clear_avi_infoframe || 714 + !bridge->funcs->hdmi_write_hdmi_infoframe || 715 + !bridge->funcs->hdmi_clear_hdmi_infoframe) 716 + return ERR_PTR(-EINVAL); 717 + 718 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME && 719 + (!bridge->funcs->hdmi_write_hdr_drm_infoframe || 720 + !bridge->funcs->hdmi_clear_hdr_drm_infoframe)) 721 + return ERR_PTR(-EINVAL); 722 + 723 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME && 724 + (!bridge->funcs->hdmi_write_spd_infoframe || 725 + !bridge->funcs->hdmi_clear_spd_infoframe)) 760 726 return ERR_PTR(-EINVAL); 761 727 762 728 bridge_connector->bridge_hdmi = drm_bridge_get(bridge); ··· 790 732 !bridge->hdmi_audio_spdif_playback) 791 733 return ERR_PTR(-EINVAL); 792 734 793 - if (!bridge->funcs->hdmi_audio_prepare || 735 + if (!bridge->funcs->hdmi_write_audio_infoframe || 736 + !bridge->funcs->hdmi_clear_audio_infoframe || 737 + !bridge->funcs->hdmi_audio_prepare || 794 738 !bridge->funcs->hdmi_audio_shutdown) 795 739 return ERR_PTR(-EINVAL); 796 740
+5 -3
drivers/gpu/drm/mediatek/mtk_hdmi_common.c
··· 433 433 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID 434 434 | DRM_BRIDGE_OP_HPD; 435 435 436 - if (ver_conf->bridge_funcs->hdmi_write_infoframe && 437 - ver_conf->bridge_funcs->hdmi_clear_infoframe) 438 - hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI; 436 + /* Only v2 support OP_HDMI now and it we know that it also support SPD */ 437 + if (ver_conf->bridge_funcs->hdmi_write_avi_infoframe && 438 + ver_conf->bridge_funcs->hdmi_clear_avi_infoframe) 439 + hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI | 440 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; 439 441 440 442 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 441 443 hdmi->bridge.ddc = hdmi->ddc_adpt;
+59 -51
drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
··· 145 145 return val; 146 146 } 147 147 148 - static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 148 + static int mtk_hdmi_v2_hdmi_write_audio_infoframe(struct drm_bridge *bridge, 149 + const u8 *buffer, size_t len) 149 150 { 151 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 152 + 150 153 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR); 151 154 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 152 155 ··· 161 158 162 159 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 163 160 regmap_set_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR); 161 + 162 + return 0; 164 163 } 165 164 166 - static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 165 + static int mtk_hdmi_v2_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 166 + const u8 *buffer, size_t len) 167 167 { 168 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 169 + 168 170 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 169 171 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 170 172 ··· 183 175 184 176 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 185 177 regmap_set_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 178 + 179 + return 0; 186 180 } 187 181 188 - static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 182 + static int mtk_hdmi_v2_hdmi_write_spd_infoframe(struct drm_bridge *bridge, 183 + const u8 *buffer, size_t len) 189 184 { 185 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 186 + 190 187 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 191 188 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 192 189 ··· 207 194 208 195 regmap_set_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 209 196 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 197 + 198 + return 0; 210 199 } 211 200 212 - static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 201 + static int mtk_hdmi_v2_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 202 + const u8 *buffer, size_t len) 213 203 { 204 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 205 + 214 206 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 215 207 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 216 208 ··· 231 213 232 214 regmap_set_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 233 215 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 216 + 217 + return 0; 234 218 } 235 219 236 220 static void mtk_hdmi_yuv420_downsampling(struct mtk_hdmi *hdmi, bool enable) ··· 275 255 if (ret < 0) 276 256 return ret; 277 257 278 - mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer); 258 + mtk_hdmi_v2_hdmi_write_audio_infoframe(&hdmi->bridge, buffer, sizeof(buffer)); 279 259 280 260 return 0; 281 261 } ··· 1152 1132 return MODE_OK; 1153 1133 } 1154 1134 1155 - static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge, 1156 - enum hdmi_infoframe_type type) 1135 + static int mtk_hdmi_v2_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) 1157 1136 { 1158 1137 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1159 1138 1160 - switch (type) { 1161 - case HDMI_INFOFRAME_TYPE_AUDIO: 1162 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN); 1163 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 1164 - break; 1165 - case HDMI_INFOFRAME_TYPE_AVI: 1166 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 1167 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 1168 - break; 1169 - case HDMI_INFOFRAME_TYPE_SPD: 1170 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 1171 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 1172 - break; 1173 - case HDMI_INFOFRAME_TYPE_VENDOR: 1174 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 1175 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 1176 - break; 1177 - case HDMI_INFOFRAME_TYPE_DRM: 1178 - default: 1179 - break; 1180 - }; 1139 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN); 1140 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 1181 1141 1182 1142 return 0; 1183 1143 } 1184 1144 1185 - static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge, 1186 - enum hdmi_infoframe_type type, 1187 - const u8 *buffer, size_t len) 1145 + static int mtk_hdmi_v2_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 1188 1146 { 1189 1147 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1190 1148 1191 - switch (type) { 1192 - case HDMI_INFOFRAME_TYPE_AUDIO: 1193 - mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer); 1194 - break; 1195 - case HDMI_INFOFRAME_TYPE_AVI: 1196 - mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer); 1197 - break; 1198 - case HDMI_INFOFRAME_TYPE_SPD: 1199 - mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer); 1200 - break; 1201 - case HDMI_INFOFRAME_TYPE_VENDOR: 1202 - mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer); 1203 - break; 1204 - case HDMI_INFOFRAME_TYPE_DRM: 1205 - default: 1206 - dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type); 1207 - break; 1208 - }; 1149 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 1150 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 1151 + 1152 + return 0; 1153 + } 1154 + 1155 + static int mtk_hdmi_v2_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) 1156 + { 1157 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1158 + 1159 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 1160 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 1161 + 1162 + return 0; 1163 + } 1164 + 1165 + static int mtk_hdmi_v2_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 1166 + { 1167 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1168 + 1169 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 1170 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 1209 1171 1210 1172 return 0; 1211 1173 } ··· 1331 1329 .hpd_enable = mtk_hdmi_v2_hpd_enable, 1332 1330 .hpd_disable = mtk_hdmi_v2_hpd_disable, 1333 1331 .hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid, 1334 - .hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe, 1335 - .hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe, 1332 + .hdmi_clear_audio_infoframe = mtk_hdmi_v2_hdmi_clear_audio_infoframe, 1333 + .hdmi_write_audio_infoframe = mtk_hdmi_v2_hdmi_write_audio_infoframe, 1334 + .hdmi_clear_avi_infoframe = mtk_hdmi_v2_hdmi_clear_avi_infoframe, 1335 + .hdmi_write_avi_infoframe = mtk_hdmi_v2_hdmi_write_avi_infoframe, 1336 + .hdmi_clear_spd_infoframe = mtk_hdmi_v2_hdmi_clear_spd_infoframe, 1337 + .hdmi_write_spd_infoframe = mtk_hdmi_v2_hdmi_write_spd_infoframe, 1338 + .hdmi_clear_hdmi_infoframe = mtk_hdmi_v2_hdmi_clear_hdmi_infoframe, 1339 + .hdmi_write_hdmi_infoframe = mtk_hdmi_v2_hdmi_write_hdmi_infoframe, 1336 1340 .debugfs_init = mtk_hdmi_v2_debugfs_init, 1337 1341 }; 1338 1342
+101 -94
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
··· 54 54 #define SPD_IFRAME_LINE_NUMBER 1 55 55 #define VENSPEC_IFRAME_LINE_NUMBER 3 56 56 57 - static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi, 58 - const u8 *buffer, size_t len) 57 + static int msm_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 59 58 { 59 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 60 + struct hdmi *hdmi = hdmi_bridge->hdmi; 61 + u32 val; 62 + 63 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 64 + val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND | 65 + HDMI_INFOFRAME_CTRL0_AVI_CONT); 66 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 67 + 68 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 69 + val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; 70 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 71 + 72 + return 0; 73 + } 74 + 75 + static int msm_hdmi_bridge_clear_audio_infoframe(struct drm_bridge *bridge) 76 + { 77 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 78 + struct hdmi *hdmi = hdmi_bridge->hdmi; 79 + u32 val; 80 + 81 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 82 + val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND | 83 + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT | 84 + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE | 85 + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE); 86 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 87 + 88 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 89 + val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; 90 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 91 + 92 + return 0; 93 + } 94 + 95 + static int msm_hdmi_bridge_clear_spd_infoframe(struct drm_bridge *bridge) 96 + { 97 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 98 + struct hdmi *hdmi = hdmi_bridge->hdmi; 99 + u32 val; 100 + 101 + val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 102 + val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND | 103 + HDMI_GEN_PKT_CTRL_GENERIC1_CONT | 104 + HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK); 105 + hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 106 + 107 + return 0; 108 + } 109 + 110 + static int msm_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 111 + { 112 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 113 + struct hdmi *hdmi = hdmi_bridge->hdmi; 114 + u32 val; 115 + 116 + val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 117 + val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND | 118 + HDMI_GEN_PKT_CTRL_GENERIC0_CONT | 119 + HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE | 120 + HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK); 121 + hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 122 + 123 + return 0; 124 + } 125 + 126 + static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, 127 + const u8 *buffer, size_t len) 128 + { 129 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 130 + struct hdmi *hdmi = hdmi_bridge->hdmi; 60 131 u32 buf[4] = {}; 61 132 u32 val; 62 133 int i; ··· 137 66 "failed to configure avi infoframe\n"); 138 67 return -EINVAL; 139 68 } 69 + 70 + msm_hdmi_bridge_clear_avi_infoframe(bridge); 140 71 141 72 /* 142 73 * the AVI_INFOx registers don't map exactly to how the AVI infoframes ··· 166 93 return 0; 167 94 } 168 95 169 - static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi, 170 - const u8 *buffer, size_t len) 96 + static int msm_hdmi_bridge_write_audio_infoframe(struct drm_bridge *bridge, 97 + const u8 *buffer, size_t len) 171 98 { 99 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 100 + struct hdmi *hdmi = hdmi_bridge->hdmi; 172 101 u32 val; 173 102 174 103 if (len != HDMI_INFOFRAME_SIZE(AUDIO)) { ··· 178 103 "failed to configure audio infoframe\n"); 179 104 return -EINVAL; 180 105 } 106 + 107 + msm_hdmi_bridge_clear_audio_infoframe(bridge); 181 108 182 109 hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0, 183 110 buffer[3] | ··· 203 126 return 0; 204 127 } 205 128 206 - static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi, 207 - const u8 *buffer, size_t len) 129 + static int msm_hdmi_bridge_write_spd_infoframe(struct drm_bridge *bridge, 130 + const u8 *buffer, size_t len) 208 131 { 132 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 133 + struct hdmi *hdmi = hdmi_bridge->hdmi; 209 134 u32 buf[7] = {}; 210 135 u32 val; 211 136 int i; ··· 217 138 "failed to configure SPD infoframe\n"); 218 139 return -EINVAL; 219 140 } 141 + 142 + msm_hdmi_bridge_clear_spd_infoframe(bridge); 220 143 221 144 /* checksum gets written together with the body of the frame */ 222 145 hdmi_write(hdmi, REG_HDMI_GENERIC1_HDR, ··· 240 159 return 0; 241 160 } 242 161 243 - static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi, 244 - const u8 *buffer, size_t len) 162 + static int msm_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 163 + const u8 *buffer, size_t len) 245 164 { 165 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 166 + struct hdmi *hdmi = hdmi_bridge->hdmi; 246 167 u32 buf[7] = {}; 247 168 u32 val; 248 169 int i; ··· 255 172 "failed to configure HDMI infoframe\n"); 256 173 return -EINVAL; 257 174 } 175 + 176 + msm_hdmi_bridge_clear_hdmi_infoframe(bridge); 258 177 259 178 /* checksum gets written together with the body of the frame */ 260 179 hdmi_write(hdmi, REG_HDMI_GENERIC0_HDR, ··· 277 192 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 278 193 279 194 return 0; 280 - } 281 - 282 - static int msm_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, 283 - enum hdmi_infoframe_type type) 284 - { 285 - struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 286 - struct hdmi *hdmi = hdmi_bridge->hdmi; 287 - u32 val; 288 - 289 - switch (type) { 290 - case HDMI_INFOFRAME_TYPE_AVI: 291 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 292 - val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND | 293 - HDMI_INFOFRAME_CTRL0_AVI_CONT); 294 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 295 - 296 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 297 - val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; 298 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 299 - 300 - break; 301 - 302 - case HDMI_INFOFRAME_TYPE_AUDIO: 303 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 304 - val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND | 305 - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT | 306 - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE | 307 - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE); 308 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 309 - 310 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 311 - val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; 312 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 313 - 314 - break; 315 - 316 - case HDMI_INFOFRAME_TYPE_SPD: 317 - val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 318 - val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND | 319 - HDMI_GEN_PKT_CTRL_GENERIC1_CONT | 320 - HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK); 321 - hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 322 - 323 - break; 324 - 325 - case HDMI_INFOFRAME_TYPE_VENDOR: 326 - val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 327 - val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND | 328 - HDMI_GEN_PKT_CTRL_GENERIC0_CONT | 329 - HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE | 330 - HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK); 331 - hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 332 - 333 - break; 334 - 335 - default: 336 - drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); 337 - } 338 - 339 - return 0; 340 - } 341 - 342 - static int msm_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, 343 - enum hdmi_infoframe_type type, 344 - const u8 *buffer, size_t len) 345 - { 346 - struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 347 - struct hdmi *hdmi = hdmi_bridge->hdmi; 348 - 349 - msm_hdmi_bridge_clear_infoframe(bridge, type); 350 - 351 - switch (type) { 352 - case HDMI_INFOFRAME_TYPE_AVI: 353 - return msm_hdmi_config_avi_infoframe(hdmi, buffer, len); 354 - case HDMI_INFOFRAME_TYPE_AUDIO: 355 - return msm_hdmi_config_audio_infoframe(hdmi, buffer, len); 356 - case HDMI_INFOFRAME_TYPE_SPD: 357 - return msm_hdmi_config_spd_infoframe(hdmi, buffer, len); 358 - case HDMI_INFOFRAME_TYPE_VENDOR: 359 - return msm_hdmi_config_hdmi_infoframe(hdmi, buffer, len); 360 - default: 361 - drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); 362 - return 0; 363 - } 364 195 } 365 196 366 197 static void msm_hdmi_set_timings(struct hdmi *hdmi, ··· 463 462 .hpd_enable = msm_hdmi_hpd_enable, 464 463 .hpd_disable = msm_hdmi_hpd_disable, 465 464 .hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid, 466 - .hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe, 467 - .hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe, 465 + .hdmi_clear_audio_infoframe = msm_hdmi_bridge_clear_audio_infoframe, 466 + .hdmi_write_audio_infoframe = msm_hdmi_bridge_write_audio_infoframe, 467 + .hdmi_clear_avi_infoframe = msm_hdmi_bridge_clear_avi_infoframe, 468 + .hdmi_write_avi_infoframe = msm_hdmi_bridge_write_avi_infoframe, 469 + .hdmi_clear_spd_infoframe = msm_hdmi_bridge_clear_spd_infoframe, 470 + .hdmi_write_spd_infoframe = msm_hdmi_bridge_write_spd_infoframe, 471 + .hdmi_clear_hdmi_infoframe = msm_hdmi_bridge_clear_hdmi_infoframe, 472 + .hdmi_write_hdmi_infoframe = msm_hdmi_bridge_write_hdmi_infoframe, 468 473 .hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare, 469 474 .hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown, 470 475 };
+29 -18
drivers/gpu/drm/rockchip/rk3066_hdmi.c
··· 158 158 hdmi->tmdsclk = DEFAULT_PLLA_RATE; 159 159 } 160 160 161 - static int rk3066_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, 162 - enum hdmi_infoframe_type type) 161 + static int rk3066_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 163 162 { 164 163 struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); 165 - 166 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 167 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 168 - return 0; 169 - } 170 164 171 165 hdmi_writeb(hdmi, HDMI_CP_BUF_INDEX, HDMI_INFOFRAME_AVI); 172 166 ··· 168 174 } 169 175 170 176 static int 171 - rk3066_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, 172 - enum hdmi_infoframe_type type, 173 - const u8 *buffer, size_t len) 177 + rk3066_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 178 + { 179 + /* FIXME: add support for this InfoFrame */ 180 + 181 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n"); 182 + 183 + return 0; 184 + } 185 + 186 + static int 187 + rk3066_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, 188 + const u8 *buffer, size_t len) 174 189 { 175 190 struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); 176 191 ssize_t i; 177 192 178 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 179 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 180 - return 0; 181 - } 182 - 183 - rk3066_hdmi_bridge_clear_infoframe(bridge, type); 193 + rk3066_hdmi_bridge_clear_avi_infoframe(bridge); 184 194 185 195 for (i = 0; i < len; i++) 186 196 hdmi_writeb(hdmi, HDMI_CP_BUF_ACC_HB0 + i * 4, buffer[i]); 197 + 198 + return 0; 199 + } 200 + 201 + static int 202 + rk3066_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 203 + const u8 *buffer, size_t len) 204 + { 205 + rk3066_hdmi_bridge_clear_hdmi_infoframe(bridge); 206 + 207 + /* FIXME: add support for this InfoFrame */ 187 208 188 209 return 0; 189 210 } ··· 502 493 .atomic_disable = rk3066_hdmi_bridge_atomic_disable, 503 494 .detect = rk3066_hdmi_bridge_detect, 504 495 .edid_read = rk3066_hdmi_bridge_edid_read, 505 - .hdmi_clear_infoframe = rk3066_hdmi_bridge_clear_infoframe, 506 - .hdmi_write_infoframe = rk3066_hdmi_bridge_write_infoframe, 496 + .hdmi_clear_avi_infoframe = rk3066_hdmi_bridge_clear_avi_infoframe, 497 + .hdmi_write_avi_infoframe = rk3066_hdmi_bridge_write_avi_infoframe, 498 + .hdmi_clear_hdmi_infoframe = rk3066_hdmi_bridge_clear_hdmi_infoframe, 499 + .hdmi_write_hdmi_infoframe = rk3066_hdmi_bridge_write_hdmi_infoframe, 507 500 .mode_valid = rk3066_hdmi_bridge_mode_valid, 508 501 }; 509 502
+115 -12
include/drm/drm_bridge.h
··· 785 785 unsigned long long tmds_rate); 786 786 787 787 /** 788 - * @hdmi_clear_infoframe: 788 + * @hdmi_clear_avi_infoframe: 789 789 * 790 790 * This callback clears the infoframes in the hardware during commit. 791 - * It will be called multiple times, once for every disabled infoframe 792 - * type. 793 791 * 794 792 * This callback is optional but it must be implemented by bridges that 795 793 * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 796 794 */ 797 - int (*hdmi_clear_infoframe)(struct drm_bridge *bridge, 798 - enum hdmi_infoframe_type type); 795 + int (*hdmi_clear_avi_infoframe)(struct drm_bridge *bridge); 796 + 799 797 /** 800 - * @hdmi_write_infoframe: 798 + * @hdmi_write_avi_infoframe: 801 799 * 802 - * Program the infoframe into the hardware. It will be called multiple 803 - * times, once for every updated infoframe type. 800 + * Program the infoframe into the hardware. 804 801 * 805 802 * This callback is optional but it must be implemented by bridges that 806 803 * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 807 804 */ 808 - int (*hdmi_write_infoframe)(struct drm_bridge *bridge, 809 - enum hdmi_infoframe_type type, 810 - const u8 *buffer, size_t len); 805 + int (*hdmi_write_avi_infoframe)(struct drm_bridge *bridge, 806 + const u8 *buffer, size_t len); 807 + 808 + /** 809 + * @hdmi_clear_hdmi_infoframe: 810 + * 811 + * This callback clears the infoframes in the hardware during commit. 812 + * 813 + * This callback is optional but it must be implemented by bridges that 814 + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 815 + */ 816 + int (*hdmi_clear_hdmi_infoframe)(struct drm_bridge *bridge); 817 + 818 + /** 819 + * @hdmi_write_hdmi_infoframe: 820 + * 821 + * Program the infoframe into the hardware. 822 + * 823 + * This callback is optional but it must be implemented by bridges that 824 + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 825 + */ 826 + int (*hdmi_write_hdmi_infoframe)(struct drm_bridge *bridge, 827 + const u8 *buffer, size_t len); 828 + 829 + /** 830 + * @hdmi_clear_hdr_drm_infoframe: 831 + * 832 + * This callback clears the infoframes in the hardware during commit. 833 + * 834 + * This callback is optional but it must be implemented by bridges that 835 + * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their 836 + * &drm_bridge->ops. 837 + */ 838 + int (*hdmi_clear_hdr_drm_infoframe)(struct drm_bridge *bridge); 839 + 840 + /** 841 + * @hdmi_write_hdr_drm_infoframe: 842 + * 843 + * Program the infoframe into the hardware. 844 + * 845 + * This callback is optional but it must be implemented by bridges that 846 + * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their 847 + * &drm_bridge->ops. 848 + */ 849 + int (*hdmi_write_hdr_drm_infoframe)(struct drm_bridge *bridge, 850 + const u8 *buffer, size_t len); 851 + 852 + /** 853 + * @hdmi_clear_spd_infoframe: 854 + * 855 + * This callback clears the infoframes in the hardware during commit. 856 + * 857 + * This callback is optional but it must be implemented by bridges that 858 + * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their 859 + * &drm_bridge->ops. 860 + */ 861 + int (*hdmi_clear_spd_infoframe)(struct drm_bridge *bridge); 862 + 863 + /** 864 + * @hdmi_write_spd_infoframe: 865 + * 866 + * Program the infoframe into the hardware. 867 + * 868 + * This callback is optional but it must be implemented by bridges that 869 + * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their 870 + * &drm_bridge->ops. 871 + */ 872 + int (*hdmi_write_spd_infoframe)(struct drm_bridge *bridge, 873 + const u8 *buffer, size_t len); 874 + 875 + /** 876 + * @hdmi_clear_audio_infoframe: 877 + * 878 + * This callback clears the infoframes in the hardware during commit. 879 + * 880 + * This callback is optional but it must be implemented by bridges that 881 + * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops. 882 + */ 883 + int (*hdmi_clear_audio_infoframe)(struct drm_bridge *bridge); 884 + 885 + /** 886 + * @hdmi_write_audio_infoframe: 887 + * 888 + * Program the infoframe into the hardware. 889 + * 890 + * This callback is optional but it must be implemented by bridges that 891 + * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops. 892 + */ 893 + int (*hdmi_write_audio_infoframe)(struct drm_bridge *bridge, 894 + const u8 *buffer, size_t len); 811 895 812 896 /** 813 897 * @hdmi_audio_startup: ··· 1147 1063 /** 1148 1064 * @DRM_BRIDGE_OP_HDMI: The bridge provides HDMI connector operations, 1149 1065 * including infoframes support. Bridges that set this flag must 1150 - * implement the &drm_bridge_funcs->write_infoframe callback. 1066 + * provide HDMI-related information and implement the 1067 + * &drm_bridge_funcs->clear_avi_infoframe, 1068 + * &drm_bridge_funcs->write_avi_infoframe, 1069 + * &drm_bridge_funcs->clear_hdmi_infoframe and 1070 + * &drm_bridge_funcs->write_hdmi_infoframe callbacks. 1151 1071 * 1152 1072 * Note: currently there can be at most one bridge in a chain that sets 1153 1073 * this bit. This is to simplify corresponding glue code in connector ··· 1163 1075 * Bridges that set this flag must implement the 1164 1076 * &drm_bridge_funcs->hdmi_audio_prepare and 1165 1077 * &drm_bridge_funcs->hdmi_audio_shutdown callbacks. 1078 + * If the bridge implements @DRM_BRIDGE_OP_HDMI, it also must implement 1079 + * &drm_bridge_funcs->hdmi_write_audio_infoframe and 1080 + * &drm_bridge_funcs->hdmi_cleaer_audio_infoframe callbacks. 1166 1081 * 1167 1082 * Note: currently there can be at most one bridge in a chain that sets 1168 1083 * this bit. This is to simplify corresponding glue code in connector ··· 1197 1106 * to be present. 1198 1107 */ 1199 1108 DRM_BRIDGE_OP_HDMI_CEC_ADAPTER = BIT(8), 1109 + /** 1110 + * @DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME: The bridge supports 1111 + * &drm_bridge_funcs->hdmi_write_hdr_drm_infoframe and 1112 + * &drm_bridge_funcs->hdmi_clear_hdr_drm_infoframe callbacks. 1113 + */ 1114 + DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME = BIT(9), 1115 + /** 1116 + * @DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME: The bridge supports 1117 + * &drm_bridge_funcs->hdmi_write_spd_infoframe and 1118 + * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks. 1119 + */ 1120 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME = BIT(10), 1200 1121 }; 1201 1122 1202 1123 /**