1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. 4 */ 5 6 7 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ 8 9 #include <linux/platform_device.h> 10 11 #include <drm/display/drm_dp_helper.h> 12 #include <drm/drm_edid.h> 13 14 #include "dp_catalog.h" 15 #include "dp_audio.h" 16 #include "dp_panel.h" 17 #include "dp_reg.h" 18 #include "dp_display.h" 19 #include "dp_utils.h" 20 21 struct msm_dp_audio_private { 22 struct platform_device *audio_pdev; 23 struct platform_device *pdev; 24 struct drm_device *drm_dev; 25 struct msm_dp_catalog *catalog; 26 27 u32 channels; 28 29 struct msm_dp_audio msm_dp_audio; 30 }; 31 32 static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio) 33 { 34 struct dp_sdp_header sdp_hdr = { 35 .HB0 = 0x00, 36 .HB1 = 0x02, 37 .HB2 = 0x00, 38 .HB3 = audio->channels - 1, 39 }; 40 41 msm_dp_catalog_write_audio_stream(audio->catalog, &sdp_hdr); 42 } 43 44 static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio) 45 { 46 struct dp_sdp_header sdp_hdr = { 47 .HB0 = 0x00, 48 .HB1 = 0x01, 49 .HB2 = 0x17, 50 .HB3 = 0x0 | (0x11 << 2), 51 }; 52 53 msm_dp_catalog_write_audio_timestamp(audio->catalog, &sdp_hdr); 54 } 55 56 static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio) 57 { 58 struct dp_sdp_header sdp_hdr = { 59 .HB0 = 0x00, 60 .HB1 = 0x84, 61 .HB2 = 0x1b, 62 .HB3 = 0x0 | (0x11 << 2), 63 }; 64 65 msm_dp_catalog_write_audio_infoframe(audio->catalog, &sdp_hdr); 66 } 67 68 static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio) 69 { 70 struct dp_sdp_header sdp_hdr = { 71 .HB0 = 0x00, 72 .HB1 = 0x05, 73 .HB2 = 0x0f, 74 .HB3 = 0x00, 75 }; 76 77 msm_dp_catalog_write_audio_copy_mgmt(audio->catalog, &sdp_hdr); 78 } 79 80 static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio) 81 { 82 struct dp_sdp_header sdp_hdr = { 83 .HB0 = 0x00, 84 .HB1 = 0x06, 85 .HB2 = 0x0f, 86 .HB3 = 0x00, 87 }; 88 89 msm_dp_catalog_write_audio_isrc(audio->catalog, &sdp_hdr); 90 } 91 92 static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio) 93 { 94 msm_dp_catalog_audio_config_sdp(audio->catalog); 95 96 msm_dp_audio_stream_sdp(audio); 97 msm_dp_audio_timestamp_sdp(audio); 98 msm_dp_audio_infoframe_sdp(audio); 99 msm_dp_audio_copy_management_sdp(audio); 100 msm_dp_audio_isrc_sdp(audio); 101 } 102 103 static void msm_dp_audio_setup_acr(struct msm_dp_audio_private *audio) 104 { 105 u32 select = 0; 106 struct msm_dp_catalog *catalog = audio->catalog; 107 108 switch (audio->msm_dp_audio.bw_code) { 109 case DP_LINK_BW_1_62: 110 select = 0; 111 break; 112 case DP_LINK_BW_2_7: 113 select = 1; 114 break; 115 case DP_LINK_BW_5_4: 116 select = 2; 117 break; 118 case DP_LINK_BW_8_1: 119 select = 3; 120 break; 121 default: 122 drm_dbg_dp(audio->drm_dev, "Unknown link rate\n"); 123 select = 0; 124 break; 125 } 126 127 msm_dp_catalog_audio_config_acr(catalog, select); 128 } 129 130 static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio) 131 { 132 struct msm_dp_catalog *catalog = audio->catalog; 133 u32 safe_to_exit_level = 0; 134 135 switch (audio->msm_dp_audio.lane_count) { 136 case 1: 137 safe_to_exit_level = 14; 138 break; 139 case 2: 140 safe_to_exit_level = 8; 141 break; 142 case 4: 143 safe_to_exit_level = 5; 144 break; 145 default: 146 safe_to_exit_level = 14; 147 drm_dbg_dp(audio->drm_dev, 148 "setting the default safe_to_exit_level = %u\n", 149 safe_to_exit_level); 150 break; 151 } 152 153 msm_dp_catalog_audio_sfe_level(catalog, safe_to_exit_level); 154 } 155 156 static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable) 157 { 158 struct msm_dp_catalog *catalog = audio->catalog; 159 160 msm_dp_catalog_audio_enable(catalog, enable); 161 } 162 163 static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev) 164 { 165 struct msm_dp_audio *msm_dp_audio; 166 struct msm_dp *msm_dp_display; 167 168 if (!pdev) { 169 DRM_ERROR("invalid input\n"); 170 return ERR_PTR(-ENODEV); 171 } 172 173 msm_dp_display = platform_get_drvdata(pdev); 174 if (!msm_dp_display) { 175 DRM_ERROR("invalid input\n"); 176 return ERR_PTR(-ENODEV); 177 } 178 179 msm_dp_audio = msm_dp_display->msm_dp_audio; 180 181 if (!msm_dp_audio) { 182 DRM_ERROR("invalid msm_dp_audio data\n"); 183 return ERR_PTR(-EINVAL); 184 } 185 186 return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio); 187 } 188 189 static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data, 190 hdmi_codec_plugged_cb fn, 191 struct device *codec_dev) 192 { 193 194 struct platform_device *pdev; 195 struct msm_dp *msm_dp_display; 196 197 pdev = to_platform_device(dev); 198 if (!pdev) { 199 pr_err("invalid input\n"); 200 return -ENODEV; 201 } 202 203 msm_dp_display = platform_get_drvdata(pdev); 204 if (!msm_dp_display) { 205 pr_err("invalid input\n"); 206 return -ENODEV; 207 } 208 209 return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev); 210 } 211 212 static int msm_dp_audio_get_eld(struct device *dev, 213 void *data, uint8_t *buf, size_t len) 214 { 215 struct platform_device *pdev; 216 struct msm_dp *msm_dp_display; 217 218 pdev = to_platform_device(dev); 219 220 if (!pdev) { 221 DRM_ERROR("invalid input\n"); 222 return -ENODEV; 223 } 224 225 msm_dp_display = platform_get_drvdata(pdev); 226 if (!msm_dp_display) { 227 DRM_ERROR("invalid input\n"); 228 return -ENODEV; 229 } 230 231 mutex_lock(&msm_dp_display->connector->eld_mutex); 232 memcpy(buf, msm_dp_display->connector->eld, 233 min(sizeof(msm_dp_display->connector->eld), len)); 234 mutex_unlock(&msm_dp_display->connector->eld_mutex); 235 236 return 0; 237 } 238 239 int msm_dp_audio_hw_params(struct device *dev, 240 void *data, 241 struct hdmi_codec_daifmt *daifmt, 242 struct hdmi_codec_params *params) 243 { 244 int rc = 0; 245 struct msm_dp_audio_private *audio; 246 struct platform_device *pdev; 247 struct msm_dp *msm_dp_display; 248 249 pdev = to_platform_device(dev); 250 msm_dp_display = platform_get_drvdata(pdev); 251 252 /* 253 * there could be cases where sound card can be opened even 254 * before OR even when DP is not connected . This can cause 255 * unclocked access as the audio subsystem relies on the DP 256 * driver to maintain the correct state of clocks. To protect 257 * such cases check for connection status and bail out if not 258 * connected. 259 */ 260 if (!msm_dp_display->power_on) { 261 rc = -EINVAL; 262 goto end; 263 } 264 265 audio = msm_dp_audio_get_data(pdev); 266 if (IS_ERR(audio)) { 267 rc = PTR_ERR(audio); 268 goto end; 269 } 270 271 audio->channels = params->channels; 272 273 msm_dp_audio_setup_sdp(audio); 274 msm_dp_audio_setup_acr(audio); 275 msm_dp_audio_safe_to_exit_level(audio); 276 msm_dp_audio_enable(audio, true); 277 msm_dp_display_signal_audio_start(msm_dp_display); 278 msm_dp_display->audio_enabled = true; 279 280 end: 281 return rc; 282 } 283 284 static void msm_dp_audio_shutdown(struct device *dev, void *data) 285 { 286 struct msm_dp_audio_private *audio; 287 struct platform_device *pdev; 288 struct msm_dp *msm_dp_display; 289 290 pdev = to_platform_device(dev); 291 msm_dp_display = platform_get_drvdata(pdev); 292 audio = msm_dp_audio_get_data(pdev); 293 if (IS_ERR(audio)) { 294 DRM_ERROR("failed to get audio data\n"); 295 return; 296 } 297 298 /* 299 * if audio was not enabled there is no need 300 * to execute the shutdown and we can bail out early. 301 * This also makes sure that we dont cause an unclocked 302 * access when audio subsystem calls this without DP being 303 * connected. is_connected cannot be used here as its set 304 * to false earlier than this call 305 */ 306 if (!msm_dp_display->audio_enabled) 307 return; 308 309 msm_dp_audio_enable(audio, false); 310 /* signal the dp display to safely shutdown clocks */ 311 msm_dp_display_signal_audio_complete(msm_dp_display); 312 } 313 314 static const struct hdmi_codec_ops msm_dp_audio_codec_ops = { 315 .hw_params = msm_dp_audio_hw_params, 316 .audio_shutdown = msm_dp_audio_shutdown, 317 .get_eld = msm_dp_audio_get_eld, 318 .hook_plugged_cb = msm_dp_audio_hook_plugged_cb, 319 }; 320 321 static struct hdmi_codec_pdata codec_data = { 322 .ops = &msm_dp_audio_codec_ops, 323 .max_i2s_channels = 8, 324 .i2s = 1, 325 }; 326 327 void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio) 328 { 329 struct msm_dp_audio_private *audio_priv; 330 331 audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio); 332 333 if (audio_priv->audio_pdev) { 334 platform_device_unregister(audio_priv->audio_pdev); 335 audio_priv->audio_pdev = NULL; 336 } 337 } 338 339 int msm_dp_register_audio_driver(struct device *dev, 340 struct msm_dp_audio *msm_dp_audio) 341 { 342 struct msm_dp_audio_private *audio_priv; 343 344 audio_priv = container_of(msm_dp_audio, 345 struct msm_dp_audio_private, msm_dp_audio); 346 347 audio_priv->audio_pdev = platform_device_register_data(dev, 348 HDMI_CODEC_DRV_NAME, 349 PLATFORM_DEVID_AUTO, 350 &codec_data, 351 sizeof(codec_data)); 352 return PTR_ERR_OR_ZERO(audio_priv->audio_pdev); 353 } 354 355 struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev, 356 struct msm_dp_catalog *catalog) 357 { 358 int rc = 0; 359 struct msm_dp_audio_private *audio; 360 struct msm_dp_audio *msm_dp_audio; 361 362 if (!pdev || !catalog) { 363 DRM_ERROR("invalid input\n"); 364 rc = -EINVAL; 365 goto error; 366 } 367 368 audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL); 369 if (!audio) { 370 rc = -ENOMEM; 371 goto error; 372 } 373 374 audio->pdev = pdev; 375 audio->catalog = catalog; 376 377 msm_dp_audio = &audio->msm_dp_audio; 378 379 return msm_dp_audio; 380 error: 381 return ERR_PTR(rc); 382 } 383 384 void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio) 385 { 386 struct msm_dp_audio_private *audio; 387 388 if (!msm_dp_audio) 389 return; 390 391 audio = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio); 392 393 devm_kfree(&audio->pdev->dev, audio); 394 } 395