aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud Pouliquen <arnaud.pouliquen@st.com>2016-09-30 11:17:00 -0400
committerVincent Abriou <vincent.abriou@st.com>2017-01-06 09:12:03 -0500
commitdd841870d0f5d170175b25083365e4e3024c2d3b (patch)
treeb9b9b9a00bb4ab36a5cd63f211ffea65609a54a4
parent2cf026ae85c42f253feb9f420d1b4bc99bd5503d (diff)
drm/sti: allow audio playback on HDMI even if disabled.
This fix allows to play audio while HDMI is disconnected. When HDMI is disable, audio configuration is stored and samples are dropped (by HDMI IP). When HDMI is enabled, audio HDMI configuration is applied and samples are outputted on HDMI wire. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> Acked-by: Vincent Abriou <vincent.abriou@st.com>
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c205
1 files changed, 101 insertions, 104 deletions
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 376b0763c874..9c0025e9699e 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -788,6 +788,95 @@ static void sti_hdmi_disable(struct drm_bridge *bridge)
788 hdmi->enabled = false; 788 hdmi->enabled = false;
789} 789}
790 790
791/**
792 * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
793 * clocks. None-coherent clocks means that audio and TMDS clocks have not the
794 * same source (drifts between clocks). In this case assumption is that CTS is
795 * automatically calculated by hardware.
796 *
797 * @audio_fs: audio frame clock frequency in Hz
798 *
799 * Values computed are based on table described in HDMI specification 1.4b
800 *
801 * Returns n value.
802 */
803static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs)
804{
805 unsigned int n;
806
807 switch (audio_fs) {
808 case 32000:
809 n = 4096;
810 break;
811 case 44100:
812 n = 6272;
813 break;
814 case 48000:
815 n = 6144;
816 break;
817 case 88200:
818 n = 6272 * 2;
819 break;
820 case 96000:
821 n = 6144 * 2;
822 break;
823 case 176400:
824 n = 6272 * 4;
825 break;
826 case 192000:
827 n = 6144 * 4;
828 break;
829 default:
830 /* Not pre-defined, recommended value: 128 * fs / 1000 */
831 n = (audio_fs * 128) / 1000;
832 }
833
834 return n;
835}
836
837static int hdmi_audio_configure(struct sti_hdmi *hdmi)
838{
839 int audio_cfg, n;
840 struct hdmi_audio_params *params = &hdmi->audio;
841 struct hdmi_audio_infoframe *info = &params->cea;
842
843 DRM_DEBUG_DRIVER("\n");
844
845 if (!hdmi->enabled)
846 return 0;
847
848 /* update N parameter */
849 n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
850
851 DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n",
852 params->sample_rate, hdmi->mode.clock * 1000, n);
853 hdmi_write(hdmi, n, HDMI_AUDN);
854
855 /* update HDMI registers according to configuration */
856 audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID |
857 HDMI_AUD_CFG_ONE_BIT_INVALID;
858
859 switch (info->channels) {
860 case 8:
861 audio_cfg |= HDMI_AUD_CFG_CH78_VALID;
862 case 6:
863 audio_cfg |= HDMI_AUD_CFG_CH56_VALID;
864 case 4:
865 audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH;
866 case 2:
867 audio_cfg |= HDMI_AUD_CFG_CH12_VALID;
868 break;
869 default:
870 DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n",
871 info->channels);
872 return -EINVAL;
873 }
874
875 hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
876
877 return hdmi_audio_infoframe_config(hdmi);
878}
879
791static void sti_hdmi_pre_enable(struct drm_bridge *bridge) 880static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
792{ 881{
793 struct sti_hdmi *hdmi = bridge->driver_private; 882 struct sti_hdmi *hdmi = bridge->driver_private;
@@ -826,9 +915,12 @@ static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
826 if (hdmi_avi_infoframe_config(hdmi)) 915 if (hdmi_avi_infoframe_config(hdmi))
827 DRM_ERROR("Unable to configure AVI infoframe\n"); 916 DRM_ERROR("Unable to configure AVI infoframe\n");
828 917
829 /* Program AUDIO infoframe */ 918 if (hdmi->audio.enabled) {
830 if (hdmi_audio_infoframe_config(hdmi)) 919 if (hdmi_audio_configure(hdmi))
831 DRM_ERROR("Unable to configure AUDIO infoframe\n"); 920 DRM_ERROR("Unable to configure audio\n");
921 } else {
922 hdmi_audio_infoframe_config(hdmi);
923 }
832 924
833 /* Program VS infoframe */ 925 /* Program VS infoframe */
834 if (hdmi_vendor_infoframe_config(hdmi)) 926 if (hdmi_vendor_infoframe_config(hdmi))
@@ -1078,97 +1170,6 @@ static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev)
1078 return NULL; 1170 return NULL;
1079} 1171}
1080 1172
1081/**
1082 * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
1083 * clocks. None-coherent clocks means that audio and TMDS clocks have not the
1084 * same source (drifts between clocks). In this case assumption is that CTS is
1085 * automatically calculated by hardware.
1086 *
1087 * @audio_fs: audio frame clock frequency in Hz
1088 *
1089 * Values computed are based on table described in HDMI specification 1.4b
1090 *
1091 * Returns n value.
1092 */
1093static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs)
1094{
1095 unsigned int n;
1096
1097 switch (audio_fs) {
1098 case 32000:
1099 n = 4096;
1100 break;
1101 case 44100:
1102 n = 6272;
1103 break;
1104 case 48000:
1105 n = 6144;
1106 break;
1107 case 88200:
1108 n = 6272 * 2;
1109 break;
1110 case 96000:
1111 n = 6144 * 2;
1112 break;
1113 case 176400:
1114 n = 6272 * 4;
1115 break;
1116 case 192000:
1117 n = 6144 * 4;
1118 break;
1119 default:
1120 /* Not pre-defined, recommended value: 128 * fs / 1000 */
1121 n = (audio_fs * 128) / 1000;
1122 }
1123
1124 return n;
1125}
1126
1127static int hdmi_audio_configure(struct sti_hdmi *hdmi,
1128 struct hdmi_audio_params *params)
1129{
1130 int audio_cfg, n;
1131 struct hdmi_audio_infoframe *info = &params->cea;
1132
1133 DRM_DEBUG_DRIVER("\n");
1134
1135 if (!hdmi->enabled)
1136 return 0;
1137
1138 /* update N parameter */
1139 n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
1140
1141 DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n",
1142 params->sample_rate, hdmi->mode.clock * 1000, n);
1143 hdmi_write(hdmi, n, HDMI_AUDN);
1144
1145 /* update HDMI registers according to configuration */
1146 audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID |
1147 HDMI_AUD_CFG_ONE_BIT_INVALID;
1148
1149 switch (info->channels) {
1150 case 8:
1151 audio_cfg |= HDMI_AUD_CFG_CH78_VALID;
1152 case 6:
1153 audio_cfg |= HDMI_AUD_CFG_CH56_VALID;
1154 case 4:
1155 audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH;
1156 case 2:
1157 audio_cfg |= HDMI_AUD_CFG_CH12_VALID;
1158 break;
1159 default:
1160 DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n",
1161 info->channels);
1162 return -EINVAL;
1163 }
1164
1165 hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
1166
1167 hdmi->audio = *params;
1168
1169 return hdmi_audio_infoframe_config(hdmi);
1170}
1171
1172static void hdmi_audio_shutdown(struct device *dev, void *data) 1173static void hdmi_audio_shutdown(struct device *dev, void *data)
1173{ 1174{
1174 struct sti_hdmi *hdmi = dev_get_drvdata(dev); 1175 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
@@ -1192,17 +1193,9 @@ static int hdmi_audio_hw_params(struct device *dev,
1192{ 1193{
1193 struct sti_hdmi *hdmi = dev_get_drvdata(dev); 1194 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1194 int ret; 1195 int ret;
1195 struct hdmi_audio_params audio = {
1196 .sample_width = params->sample_width,
1197 .sample_rate = params->sample_rate,
1198 .cea = params->cea,
1199 };
1200 1196
1201 DRM_DEBUG_DRIVER("\n"); 1197 DRM_DEBUG_DRIVER("\n");
1202 1198
1203 if (!hdmi->enabled)
1204 return 0;
1205
1206 if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv || 1199 if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv ||
1207 daifmt->frame_clk_inv || daifmt->bit_clk_master || 1200 daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1208 daifmt->frame_clk_master) { 1201 daifmt->frame_clk_master) {
@@ -1213,9 +1206,13 @@ static int hdmi_audio_hw_params(struct device *dev,
1213 return -EINVAL; 1206 return -EINVAL;
1214 } 1207 }
1215 1208
1216 audio.enabled = true; 1209 hdmi->audio.sample_width = params->sample_width;
1210 hdmi->audio.sample_rate = params->sample_rate;
1211 hdmi->audio.cea = params->cea;
1212
1213 hdmi->audio.enabled = true;
1217 1214
1218 ret = hdmi_audio_configure(hdmi, &audio); 1215 ret = hdmi_audio_configure(hdmi);
1219 if (ret < 0) 1216 if (ret < 0)
1220 return ret; 1217 return ret;
1221 1218