diff options
| -rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 350 |
1 files changed, 176 insertions, 174 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index dc23ae5374d1..cca2f397eea7 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -820,6 +820,182 @@ tda998x_configure_audio(struct tda998x_priv *priv, | |||
| 820 | return tda998x_write_aif(priv, ¶ms->cea); | 820 | return tda998x_write_aif(priv, ¶ms->cea); |
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | /* DRM connector functions */ | ||
| 824 | |||
| 825 | static int tda998x_connector_dpms(struct drm_connector *connector, int mode) | ||
| 826 | { | ||
| 827 | if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC)) | ||
| 828 | return drm_atomic_helper_connector_dpms(connector, mode); | ||
| 829 | else | ||
| 830 | return drm_helper_connector_dpms(connector, mode); | ||
| 831 | } | ||
| 832 | |||
| 833 | static int tda998x_connector_fill_modes(struct drm_connector *connector, | ||
| 834 | uint32_t maxX, uint32_t maxY) | ||
| 835 | { | ||
| 836 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 837 | int ret; | ||
| 838 | |||
| 839 | ret = drm_helper_probe_single_connector_modes(connector, maxX, maxY); | ||
| 840 | |||
| 841 | if (connector->edid_blob_ptr) { | ||
| 842 | struct edid *edid = (void *)connector->edid_blob_ptr->data; | ||
| 843 | |||
| 844 | priv->sink_has_audio = drm_detect_monitor_audio(edid); | ||
| 845 | } else { | ||
| 846 | priv->sink_has_audio = false; | ||
| 847 | } | ||
| 848 | |||
| 849 | return ret; | ||
| 850 | } | ||
| 851 | |||
| 852 | static enum drm_connector_status | ||
| 853 | tda998x_connector_detect(struct drm_connector *connector, bool force) | ||
| 854 | { | ||
| 855 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 856 | u8 val = cec_read(priv, REG_CEC_RXSHPDLEV); | ||
| 857 | |||
| 858 | return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : | ||
| 859 | connector_status_disconnected; | ||
| 860 | } | ||
| 861 | |||
| 862 | static void tda998x_connector_destroy(struct drm_connector *connector) | ||
| 863 | { | ||
| 864 | drm_connector_cleanup(connector); | ||
| 865 | } | ||
| 866 | |||
| 867 | static const struct drm_connector_funcs tda998x_connector_funcs = { | ||
| 868 | .dpms = tda998x_connector_dpms, | ||
| 869 | .reset = drm_atomic_helper_connector_reset, | ||
| 870 | .fill_modes = tda998x_connector_fill_modes, | ||
| 871 | .detect = tda998x_connector_detect, | ||
| 872 | .destroy = tda998x_connector_destroy, | ||
| 873 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | ||
| 874 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | ||
| 875 | }; | ||
| 876 | |||
| 877 | static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length) | ||
| 878 | { | ||
| 879 | struct tda998x_priv *priv = data; | ||
| 880 | u8 offset, segptr; | ||
| 881 | int ret, i; | ||
| 882 | |||
| 883 | offset = (blk & 1) ? 128 : 0; | ||
| 884 | segptr = blk / 2; | ||
| 885 | |||
| 886 | reg_write(priv, REG_DDC_ADDR, 0xa0); | ||
| 887 | reg_write(priv, REG_DDC_OFFS, offset); | ||
| 888 | reg_write(priv, REG_DDC_SEGM_ADDR, 0x60); | ||
| 889 | reg_write(priv, REG_DDC_SEGM, segptr); | ||
| 890 | |||
| 891 | /* enable reading EDID: */ | ||
| 892 | priv->wq_edid_wait = 1; | ||
| 893 | reg_write(priv, REG_EDID_CTRL, 0x1); | ||
| 894 | |||
| 895 | /* flag must be cleared by sw: */ | ||
| 896 | reg_write(priv, REG_EDID_CTRL, 0x0); | ||
| 897 | |||
| 898 | /* wait for block read to complete: */ | ||
| 899 | if (priv->hdmi->irq) { | ||
| 900 | i = wait_event_timeout(priv->wq_edid, | ||
| 901 | !priv->wq_edid_wait, | ||
| 902 | msecs_to_jiffies(100)); | ||
| 903 | if (i < 0) { | ||
| 904 | dev_err(&priv->hdmi->dev, "read edid wait err %d\n", i); | ||
| 905 | return i; | ||
| 906 | } | ||
| 907 | } else { | ||
| 908 | for (i = 100; i > 0; i--) { | ||
| 909 | msleep(1); | ||
| 910 | ret = reg_read(priv, REG_INT_FLAGS_2); | ||
| 911 | if (ret < 0) | ||
| 912 | return ret; | ||
| 913 | if (ret & INT_FLAGS_2_EDID_BLK_RD) | ||
| 914 | break; | ||
| 915 | } | ||
| 916 | } | ||
| 917 | |||
| 918 | if (i == 0) { | ||
| 919 | dev_err(&priv->hdmi->dev, "read edid timeout\n"); | ||
| 920 | return -ETIMEDOUT; | ||
| 921 | } | ||
| 922 | |||
| 923 | ret = reg_read_range(priv, REG_EDID_DATA_0, buf, length); | ||
| 924 | if (ret != length) { | ||
| 925 | dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", | ||
| 926 | blk, ret); | ||
| 927 | return ret; | ||
| 928 | } | ||
| 929 | |||
| 930 | return 0; | ||
| 931 | } | ||
| 932 | |||
| 933 | static int tda998x_connector_get_modes(struct drm_connector *connector) | ||
| 934 | { | ||
| 935 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 936 | struct edid *edid; | ||
| 937 | int n; | ||
| 938 | |||
| 939 | /* | ||
| 940 | * If we get killed while waiting for the HPD timeout, return | ||
| 941 | * no modes found: we are not in a restartable path, so we | ||
| 942 | * can't handle signals gracefully. | ||
| 943 | */ | ||
| 944 | if (tda998x_edid_delay_wait(priv)) | ||
| 945 | return 0; | ||
| 946 | |||
| 947 | if (priv->rev == TDA19988) | ||
| 948 | reg_clear(priv, REG_TX4, TX4_PD_RAM); | ||
| 949 | |||
| 950 | edid = drm_do_get_edid(connector, read_edid_block, priv); | ||
| 951 | |||
| 952 | if (priv->rev == TDA19988) | ||
| 953 | reg_set(priv, REG_TX4, TX4_PD_RAM); | ||
| 954 | |||
| 955 | if (!edid) { | ||
| 956 | dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); | ||
| 957 | return 0; | ||
| 958 | } | ||
| 959 | |||
| 960 | drm_mode_connector_update_edid_property(connector, edid); | ||
| 961 | n = drm_add_edid_modes(connector, edid); | ||
| 962 | drm_edid_to_eld(connector, edid); | ||
| 963 | |||
| 964 | kfree(edid); | ||
| 965 | |||
| 966 | return n; | ||
| 967 | } | ||
| 968 | |||
| 969 | static int tda998x_connector_mode_valid(struct drm_connector *connector, | ||
| 970 | struct drm_display_mode *mode) | ||
| 971 | { | ||
| 972 | /* TDA19988 dotclock can go up to 165MHz */ | ||
| 973 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 974 | |||
| 975 | if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) | ||
| 976 | return MODE_CLOCK_HIGH; | ||
| 977 | if (mode->htotal >= BIT(13)) | ||
| 978 | return MODE_BAD_HVALUE; | ||
| 979 | if (mode->vtotal >= BIT(11)) | ||
| 980 | return MODE_BAD_VVALUE; | ||
| 981 | return MODE_OK; | ||
| 982 | } | ||
| 983 | |||
| 984 | static struct drm_encoder * | ||
| 985 | tda998x_connector_best_encoder(struct drm_connector *connector) | ||
| 986 | { | ||
| 987 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 988 | |||
| 989 | return &priv->encoder; | ||
| 990 | } | ||
| 991 | |||
| 992 | static | ||
| 993 | const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { | ||
| 994 | .get_modes = tda998x_connector_get_modes, | ||
| 995 | .mode_valid = tda998x_connector_mode_valid, | ||
| 996 | .best_encoder = tda998x_connector_best_encoder, | ||
| 997 | }; | ||
| 998 | |||
| 823 | /* DRM encoder functions */ | 999 | /* DRM encoder functions */ |
| 824 | 1000 | ||
| 825 | static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) | 1001 | static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) |
| @@ -855,21 +1031,6 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 855 | priv->dpms = mode; | 1031 | priv->dpms = mode; |
| 856 | } | 1032 | } |
| 857 | 1033 | ||
| 858 | static int tda998x_connector_mode_valid(struct drm_connector *connector, | ||
| 859 | struct drm_display_mode *mode) | ||
| 860 | { | ||
| 861 | /* TDA19988 dotclock can go up to 165MHz */ | ||
| 862 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 863 | |||
| 864 | if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000)) | ||
| 865 | return MODE_CLOCK_HIGH; | ||
| 866 | if (mode->htotal >= BIT(13)) | ||
| 867 | return MODE_BAD_HVALUE; | ||
| 868 | if (mode->vtotal >= BIT(11)) | ||
| 869 | return MODE_BAD_VVALUE; | ||
| 870 | return MODE_OK; | ||
| 871 | } | ||
| 872 | |||
| 873 | static void | 1034 | static void |
| 874 | tda998x_encoder_mode_set(struct drm_encoder *encoder, | 1035 | tda998x_encoder_mode_set(struct drm_encoder *encoder, |
| 875 | struct drm_display_mode *mode, | 1036 | struct drm_display_mode *mode, |
| @@ -1080,127 +1241,6 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1080 | mutex_unlock(&priv->audio_mutex); | 1241 | mutex_unlock(&priv->audio_mutex); |
| 1081 | } | 1242 | } |
| 1082 | 1243 | ||
| 1083 | static int tda998x_connector_fill_modes(struct drm_connector *connector, | ||
| 1084 | uint32_t maxX, uint32_t maxY) | ||
| 1085 | { | ||
| 1086 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 1087 | int ret; | ||
| 1088 | |||
| 1089 | ret = drm_helper_probe_single_connector_modes(connector, maxX, maxY); | ||
| 1090 | |||
| 1091 | if (connector->edid_blob_ptr) { | ||
| 1092 | struct edid *edid = (void *)connector->edid_blob_ptr->data; | ||
| 1093 | |||
| 1094 | priv->sink_has_audio = drm_detect_monitor_audio(edid); | ||
| 1095 | } else { | ||
| 1096 | priv->sink_has_audio = false; | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | return ret; | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | static enum drm_connector_status | ||
| 1103 | tda998x_connector_detect(struct drm_connector *connector, bool force) | ||
| 1104 | { | ||
| 1105 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 1106 | u8 val = cec_read(priv, REG_CEC_RXSHPDLEV); | ||
| 1107 | |||
| 1108 | return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : | ||
| 1109 | connector_status_disconnected; | ||
| 1110 | } | ||
| 1111 | |||
| 1112 | static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length) | ||
| 1113 | { | ||
| 1114 | struct tda998x_priv *priv = data; | ||
| 1115 | u8 offset, segptr; | ||
| 1116 | int ret, i; | ||
| 1117 | |||
| 1118 | offset = (blk & 1) ? 128 : 0; | ||
| 1119 | segptr = blk / 2; | ||
| 1120 | |||
| 1121 | reg_write(priv, REG_DDC_ADDR, 0xa0); | ||
| 1122 | reg_write(priv, REG_DDC_OFFS, offset); | ||
| 1123 | reg_write(priv, REG_DDC_SEGM_ADDR, 0x60); | ||
| 1124 | reg_write(priv, REG_DDC_SEGM, segptr); | ||
| 1125 | |||
| 1126 | /* enable reading EDID: */ | ||
| 1127 | priv->wq_edid_wait = 1; | ||
| 1128 | reg_write(priv, REG_EDID_CTRL, 0x1); | ||
| 1129 | |||
| 1130 | /* flag must be cleared by sw: */ | ||
| 1131 | reg_write(priv, REG_EDID_CTRL, 0x0); | ||
| 1132 | |||
| 1133 | /* wait for block read to complete: */ | ||
| 1134 | if (priv->hdmi->irq) { | ||
| 1135 | i = wait_event_timeout(priv->wq_edid, | ||
| 1136 | !priv->wq_edid_wait, | ||
| 1137 | msecs_to_jiffies(100)); | ||
| 1138 | if (i < 0) { | ||
| 1139 | dev_err(&priv->hdmi->dev, "read edid wait err %d\n", i); | ||
| 1140 | return i; | ||
| 1141 | } | ||
| 1142 | } else { | ||
| 1143 | for (i = 100; i > 0; i--) { | ||
| 1144 | msleep(1); | ||
| 1145 | ret = reg_read(priv, REG_INT_FLAGS_2); | ||
| 1146 | if (ret < 0) | ||
| 1147 | return ret; | ||
| 1148 | if (ret & INT_FLAGS_2_EDID_BLK_RD) | ||
| 1149 | break; | ||
| 1150 | } | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | if (i == 0) { | ||
| 1154 | dev_err(&priv->hdmi->dev, "read edid timeout\n"); | ||
| 1155 | return -ETIMEDOUT; | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | ret = reg_read_range(priv, REG_EDID_DATA_0, buf, length); | ||
| 1159 | if (ret != length) { | ||
| 1160 | dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", | ||
| 1161 | blk, ret); | ||
| 1162 | return ret; | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | return 0; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | static int tda998x_connector_get_modes(struct drm_connector *connector) | ||
| 1169 | { | ||
| 1170 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 1171 | struct edid *edid; | ||
| 1172 | int n; | ||
| 1173 | |||
| 1174 | /* | ||
| 1175 | * If we get killed while waiting for the HPD timeout, return | ||
| 1176 | * no modes found: we are not in a restartable path, so we | ||
| 1177 | * can't handle signals gracefully. | ||
| 1178 | */ | ||
| 1179 | if (tda998x_edid_delay_wait(priv)) | ||
| 1180 | return 0; | ||
| 1181 | |||
| 1182 | if (priv->rev == TDA19988) | ||
| 1183 | reg_clear(priv, REG_TX4, TX4_PD_RAM); | ||
| 1184 | |||
| 1185 | edid = drm_do_get_edid(connector, read_edid_block, priv); | ||
| 1186 | |||
| 1187 | if (priv->rev == TDA19988) | ||
| 1188 | reg_set(priv, REG_TX4, TX4_PD_RAM); | ||
| 1189 | |||
| 1190 | if (!edid) { | ||
| 1191 | dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); | ||
| 1192 | return 0; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | drm_mode_connector_update_edid_property(connector, edid); | ||
| 1196 | n = drm_add_edid_modes(connector, edid); | ||
| 1197 | drm_edid_to_eld(connector, edid); | ||
| 1198 | |||
| 1199 | kfree(edid); | ||
| 1200 | |||
| 1201 | return n; | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | static void tda998x_encoder_set_polling(struct tda998x_priv *priv, | 1244 | static void tda998x_encoder_set_polling(struct tda998x_priv *priv, |
| 1205 | struct drm_connector *connector) | 1245 | struct drm_connector *connector) |
| 1206 | { | 1246 | { |
| @@ -1579,44 +1619,6 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = { | |||
| 1579 | .destroy = tda998x_encoder_destroy, | 1619 | .destroy = tda998x_encoder_destroy, |
| 1580 | }; | 1620 | }; |
| 1581 | 1621 | ||
| 1582 | static struct drm_encoder * | ||
| 1583 | tda998x_connector_best_encoder(struct drm_connector *connector) | ||
| 1584 | { | ||
| 1585 | struct tda998x_priv *priv = conn_to_tda998x_priv(connector); | ||
| 1586 | |||
| 1587 | return &priv->encoder; | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | static | ||
| 1591 | const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { | ||
| 1592 | .get_modes = tda998x_connector_get_modes, | ||
| 1593 | .mode_valid = tda998x_connector_mode_valid, | ||
| 1594 | .best_encoder = tda998x_connector_best_encoder, | ||
| 1595 | }; | ||
| 1596 | |||
| 1597 | static void tda998x_connector_destroy(struct drm_connector *connector) | ||
| 1598 | { | ||
| 1599 | drm_connector_cleanup(connector); | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | static int tda998x_connector_dpms(struct drm_connector *connector, int mode) | ||
| 1603 | { | ||
| 1604 | if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC)) | ||
| 1605 | return drm_atomic_helper_connector_dpms(connector, mode); | ||
| 1606 | else | ||
| 1607 | return drm_helper_connector_dpms(connector, mode); | ||
| 1608 | } | ||
| 1609 | |||
| 1610 | static const struct drm_connector_funcs tda998x_connector_funcs = { | ||
| 1611 | .dpms = tda998x_connector_dpms, | ||
| 1612 | .reset = drm_atomic_helper_connector_reset, | ||
| 1613 | .fill_modes = tda998x_connector_fill_modes, | ||
| 1614 | .detect = tda998x_connector_detect, | ||
| 1615 | .destroy = tda998x_connector_destroy, | ||
| 1616 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | ||
| 1617 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | ||
| 1618 | }; | ||
| 1619 | |||
| 1620 | static void tda998x_set_config(struct tda998x_priv *priv, | 1622 | static void tda998x_set_config(struct tda998x_priv *priv, |
| 1621 | const struct tda998x_encoder_params *p) | 1623 | const struct tda998x_encoder_params *p) |
| 1622 | { | 1624 | { |
