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

drm/tegra: hdmi: Enable audio over HDMI

In order to use the HDA codec to forward audio data to the HDMI codec it
needs the ELD that is parsed from the monitor's EDID.

Also implement an interoperability mechanism between the HDA controller
and the HDMI codec. This uses vendor-defined scratch registers to pass
data from the HDMI codec driver to the HDMI driver (that implements the
receiving end of the HDMI codec). A custom format is used to pass audio
sample rate and channel count to the HDMI driver.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+364 -108
+343 -107
drivers/gpu/drm/tegra/hdmi.c
··· 18 18 #include <drm/drm_crtc.h> 19 19 #include <drm/drm_crtc_helper.h> 20 20 21 + #include <sound/hda_verbs.h> 22 + 21 23 #include "hdmi.h" 22 24 #include "drm.h" 23 25 #include "dc.h" 26 + 27 + #define HDMI_ELD_BUFFER_SIZE 96 24 28 25 29 struct tmds_config { 26 30 unsigned int pclk; ··· 43 39 u32 fuse_override_value; 44 40 45 41 bool has_sor_io_peak_current; 42 + bool has_hda; 43 + bool has_hbr; 46 44 }; 47 45 48 46 struct tegra_hdmi { ··· 66 60 const struct tegra_hdmi_config *config; 67 61 68 62 unsigned int audio_source; 69 - unsigned int audio_freq; 63 + unsigned int audio_sample_rate; 64 + unsigned int audio_channels; 65 + 66 + unsigned int pixel_clock; 70 67 bool stereo; 71 68 bool dvi; 72 69 ··· 411 402 }; 412 403 413 404 static const struct tegra_hdmi_audio_config * 414 - tegra_hdmi_get_audio_config(unsigned int audio_freq, unsigned int pclk) 405 + tegra_hdmi_get_audio_config(unsigned int sample_rate, unsigned int pclk) 415 406 { 416 407 const struct tegra_hdmi_audio_config *table; 417 408 418 - switch (audio_freq) { 409 + switch (sample_rate) { 419 410 case 32000: 420 411 table = tegra_hdmi_audio_32k; 421 412 break; ··· 485 476 } 486 477 } 487 478 488 - static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi, unsigned int pclk) 479 + static void tegra_hdmi_write_aval(struct tegra_hdmi *hdmi, u32 value) 489 480 { 490 - struct device_node *node = hdmi->dev->of_node; 481 + static const struct { 482 + unsigned int sample_rate; 483 + unsigned int offset; 484 + } regs[] = { 485 + { 32000, HDMI_NV_PDISP_SOR_AUDIO_AVAL_0320 }, 486 + { 44100, HDMI_NV_PDISP_SOR_AUDIO_AVAL_0441 }, 487 + { 48000, HDMI_NV_PDISP_SOR_AUDIO_AVAL_0480 }, 488 + { 88200, HDMI_NV_PDISP_SOR_AUDIO_AVAL_0882 }, 489 + { 96000, HDMI_NV_PDISP_SOR_AUDIO_AVAL_0960 }, 490 + { 176400, HDMI_NV_PDISP_SOR_AUDIO_AVAL_1764 }, 491 + { 192000, HDMI_NV_PDISP_SOR_AUDIO_AVAL_1920 }, 492 + }; 493 + unsigned int i; 494 + 495 + for (i = 0; i < ARRAY_SIZE(regs); i++) { 496 + if (regs[i].sample_rate == hdmi->audio_sample_rate) { 497 + tegra_hdmi_writel(hdmi, value, regs[i].offset); 498 + break; 499 + } 500 + } 501 + } 502 + 503 + static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi) 504 + { 491 505 const struct tegra_hdmi_audio_config *config; 492 - unsigned int offset = 0; 493 - u32 value; 506 + u32 source, value; 494 507 495 508 switch (hdmi->audio_source) { 496 509 case HDA: 497 - value = AUDIO_CNTRL0_SOURCE_SELECT_HDAL; 510 + if (hdmi->config->has_hda) 511 + source = SOR_AUDIO_CNTRL0_SOURCE_SELECT_HDAL; 512 + else 513 + return -EINVAL; 514 + 498 515 break; 499 516 500 517 case SPDIF: 501 - value = AUDIO_CNTRL0_SOURCE_SELECT_SPDIF; 518 + if (hdmi->config->has_hda) 519 + source = SOR_AUDIO_CNTRL0_SOURCE_SELECT_SPDIF; 520 + else 521 + source = AUDIO_CNTRL0_SOURCE_SELECT_SPDIF; 502 522 break; 503 523 504 524 default: 505 - value = AUDIO_CNTRL0_SOURCE_SELECT_AUTO; 525 + if (hdmi->config->has_hda) 526 + source = SOR_AUDIO_CNTRL0_SOURCE_SELECT_AUTO; 527 + else 528 + source = AUDIO_CNTRL0_SOURCE_SELECT_AUTO; 506 529 break; 507 530 } 508 531 509 - if (of_device_is_compatible(node, "nvidia,tegra30-hdmi")) { 510 - value |= AUDIO_CNTRL0_ERROR_TOLERANCE(6) | 511 - AUDIO_CNTRL0_FRAMES_PER_BLOCK(0xc0); 512 - tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_CNTRL0); 513 - } else { 514 - value |= AUDIO_CNTRL0_INJECT_NULLSMPL; 515 - tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_CNTRL0); 532 + /* 533 + * Tegra30 and later use a slightly modified version of the register 534 + * layout to accomodate for changes related to supporting HDA as the 535 + * audio input source for HDMI. The source select field has moved to 536 + * the SOR_AUDIO_CNTRL0 register, but the error tolerance and frames 537 + * per block fields remain in the AUDIO_CNTRL0 register. 538 + */ 539 + if (hdmi->config->has_hda) { 540 + /* 541 + * Inject null samples into the audio FIFO for every frame in 542 + * which the codec did not receive any samples. This applies 543 + * to stereo LPCM only. 544 + * 545 + * XXX: This seems to be a remnant of MCP days when this was 546 + * used to work around issues with monitors not being able to 547 + * play back system startup sounds early. It is possibly not 548 + * needed on Linux at all. 549 + */ 550 + if (hdmi->audio_channels == 2) 551 + value = SOR_AUDIO_CNTRL0_INJECT_NULLSMPL; 552 + else 553 + value = 0; 516 554 517 - value = AUDIO_CNTRL0_ERROR_TOLERANCE(6) | 518 - AUDIO_CNTRL0_FRAMES_PER_BLOCK(0xc0); 519 - tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_CNTRL0); 555 + value |= source; 556 + 557 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_CNTRL0); 520 558 } 521 559 522 - config = tegra_hdmi_get_audio_config(hdmi->audio_freq, pclk); 560 + /* 561 + * On Tegra20, HDA is not a supported audio source and the source 562 + * select field is part of the AUDIO_CNTRL0 register. 563 + */ 564 + value = AUDIO_CNTRL0_FRAMES_PER_BLOCK(0xc0) | 565 + AUDIO_CNTRL0_ERROR_TOLERANCE(6); 566 + 567 + if (!hdmi->config->has_hda) 568 + value |= source; 569 + 570 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_CNTRL0); 571 + 572 + /* 573 + * Advertise support for High Bit-Rate on Tegra114 and later. 574 + */ 575 + if (hdmi->config->has_hbr) { 576 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_AUDIO_SPARE0); 577 + value |= SOR_AUDIO_SPARE0_HBR_ENABLE; 578 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_SPARE0); 579 + } 580 + 581 + config = tegra_hdmi_get_audio_config(hdmi->audio_sample_rate, 582 + hdmi->pixel_clock); 523 583 if (!config) { 524 - dev_err(hdmi->dev, "cannot set audio to %u at %u pclk\n", 525 - hdmi->audio_freq, pclk); 584 + dev_err(hdmi->dev, 585 + "cannot set audio to %u Hz at %u Hz pixel clock\n", 586 + hdmi->audio_sample_rate, hdmi->pixel_clock); 526 587 return -EINVAL; 527 588 } 528 589 ··· 605 526 tegra_hdmi_writel(hdmi, ACR_SUBPACK_N(config->n) | ACR_ENABLE, 606 527 HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH); 607 528 608 - value = ACR_SUBPACK_CTS(config->cts); 609 - tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW); 529 + tegra_hdmi_writel(hdmi, ACR_SUBPACK_CTS(config->cts), 530 + HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW); 610 531 611 532 value = SPARE_HW_CTS | SPARE_FORCE_SW_CTS | SPARE_CTS_RESET_VAL(1); 612 533 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_SPARE); ··· 615 536 value &= ~AUDIO_N_RESETF; 616 537 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N); 617 538 618 - if (of_device_is_compatible(node, "nvidia,tegra30-hdmi")) { 619 - switch (hdmi->audio_freq) { 620 - case 32000: 621 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0320; 622 - break; 623 - 624 - case 44100: 625 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0441; 626 - break; 627 - 628 - case 48000: 629 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0480; 630 - break; 631 - 632 - case 88200: 633 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0882; 634 - break; 635 - 636 - case 96000: 637 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0960; 638 - break; 639 - 640 - case 176400: 641 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_1764; 642 - break; 643 - 644 - case 192000: 645 - offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_1920; 646 - break; 647 - } 648 - 649 - tegra_hdmi_writel(hdmi, config->aval, offset); 650 - } 539 + if (hdmi->config->has_hda) 540 + tegra_hdmi_write_aval(hdmi, config->aval); 651 541 652 542 tegra_hdmi_setup_audio_fs_tables(hdmi); 653 543 654 544 return 0; 545 + } 546 + 547 + static void tegra_hdmi_disable_audio(struct tegra_hdmi *hdmi) 548 + { 549 + u32 value; 550 + 551 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 552 + value &= ~GENERIC_CTRL_AUDIO; 553 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 554 + } 555 + 556 + static void tegra_hdmi_enable_audio(struct tegra_hdmi *hdmi) 557 + { 558 + u32 value; 559 + 560 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 561 + value |= GENERIC_CTRL_AUDIO; 562 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 655 563 } 656 564 657 565 static inline u32 tegra_hdmi_subpack(const u8 *ptr, size_t size) ··· 710 644 u8 buffer[17]; 711 645 ssize_t err; 712 646 713 - if (hdmi->dvi) { 714 - tegra_hdmi_writel(hdmi, 0, 715 - HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 716 - return; 717 - } 718 - 719 647 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); 720 648 if (err < 0) { 721 649 dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err); ··· 723 663 } 724 664 725 665 tegra_hdmi_write_infopack(hdmi, buffer, err); 666 + } 726 667 727 - tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE, 728 - HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 668 + static void tegra_hdmi_disable_avi_infoframe(struct tegra_hdmi *hdmi) 669 + { 670 + u32 value; 671 + 672 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 673 + value &= ~INFOFRAME_CTRL_ENABLE; 674 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 675 + } 676 + 677 + static void tegra_hdmi_enable_avi_infoframe(struct tegra_hdmi *hdmi) 678 + { 679 + u32 value; 680 + 681 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 682 + value |= INFOFRAME_CTRL_ENABLE; 683 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL); 729 684 } 730 685 731 686 static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi) ··· 749 674 u8 buffer[14]; 750 675 ssize_t err; 751 676 752 - if (hdmi->dvi) { 753 - tegra_hdmi_writel(hdmi, 0, 754 - HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 755 - return; 756 - } 757 - 758 677 err = hdmi_audio_infoframe_init(&frame); 759 678 if (err < 0) { 760 679 dev_err(hdmi->dev, "failed to setup audio infoframe: %zd\n", ··· 756 687 return; 757 688 } 758 689 759 - frame.channels = 2; 690 + frame.channels = hdmi->audio_channels; 760 691 761 692 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); 762 693 if (err < 0) { ··· 772 703 * bytes can be programmed. 773 704 */ 774 705 tegra_hdmi_write_infopack(hdmi, buffer, min_t(size_t, 10, err)); 706 + } 775 707 776 - tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE, 777 - HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 708 + static void tegra_hdmi_disable_audio_infoframe(struct tegra_hdmi *hdmi) 709 + { 710 + u32 value; 711 + 712 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 713 + value &= ~INFOFRAME_CTRL_ENABLE; 714 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 715 + } 716 + 717 + static void tegra_hdmi_enable_audio_infoframe(struct tegra_hdmi *hdmi) 718 + { 719 + u32 value; 720 + 721 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 722 + value |= INFOFRAME_CTRL_ENABLE; 723 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL); 778 724 } 779 725 780 726 static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi) ··· 797 713 struct hdmi_vendor_infoframe frame; 798 714 u8 buffer[10]; 799 715 ssize_t err; 800 - u32 value; 801 - 802 - if (!hdmi->stereo) { 803 - value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 804 - value &= ~GENERIC_CTRL_ENABLE; 805 - tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 806 - return; 807 - } 808 716 809 717 hdmi_vendor_infoframe_init(&frame); 810 718 frame.s3d_struct = HDMI_3D_STRUCTURE_FRAME_PACKING; ··· 809 733 } 810 734 811 735 tegra_hdmi_write_infopack(hdmi, buffer, err); 736 + } 737 + 738 + static void tegra_hdmi_disable_stereo_infoframe(struct tegra_hdmi *hdmi) 739 + { 740 + u32 value; 741 + 742 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 743 + value &= ~GENERIC_CTRL_ENABLE; 744 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 745 + } 746 + 747 + static void tegra_hdmi_enable_stereo_infoframe(struct tegra_hdmi *hdmi) 748 + { 749 + u32 value; 812 750 813 751 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 814 752 value |= GENERIC_CTRL_ENABLE; ··· 862 772 return drm_detect_hdmi_monitor(edid); 863 773 } 864 774 775 + static enum drm_connector_status 776 + tegra_hdmi_connector_detect(struct drm_connector *connector, bool force) 777 + { 778 + struct tegra_output *output = connector_to_output(connector); 779 + struct tegra_hdmi *hdmi = to_hdmi(output); 780 + enum drm_connector_status status; 781 + 782 + status = tegra_output_connector_detect(connector, force); 783 + if (status == connector_status_connected) 784 + return status; 785 + 786 + tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE); 787 + return status; 788 + } 789 + 865 790 static const struct drm_connector_funcs tegra_hdmi_connector_funcs = { 866 791 .dpms = drm_atomic_helper_connector_dpms, 867 792 .reset = drm_atomic_helper_connector_reset, 868 - .detect = tegra_output_connector_detect, 793 + .detect = tegra_hdmi_connector_detect, 869 794 .fill_modes = drm_helper_probe_single_connector_modes, 870 795 .destroy = tegra_output_connector_destroy, 871 796 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, ··· 920 815 921 816 static void tegra_hdmi_encoder_disable(struct drm_encoder *encoder) 922 817 { 818 + struct tegra_output *output = encoder_to_output(encoder); 923 819 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 820 + struct tegra_hdmi *hdmi = to_hdmi(output); 924 821 u32 value; 925 822 926 823 /* ··· 936 829 937 830 tegra_dc_commit(dc); 938 831 } 832 + 833 + if (!hdmi->dvi) { 834 + if (hdmi->stereo) 835 + tegra_hdmi_disable_stereo_infoframe(hdmi); 836 + 837 + tegra_hdmi_disable_audio_infoframe(hdmi); 838 + tegra_hdmi_disable_avi_infoframe(hdmi); 839 + tegra_hdmi_disable_audio(hdmi); 840 + } 841 + } 842 + 843 + static void tegra_hdmi_write_eld(struct tegra_hdmi *hdmi) 844 + { 845 + size_t length = drm_eld_size(hdmi->output.connector.eld), i; 846 + u32 value; 847 + 848 + for (i = 0; i < length; i++) 849 + tegra_hdmi_writel(hdmi, i << 8 | hdmi->output.connector.eld[i], 850 + HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 851 + 852 + /* 853 + * The HDA codec will always report an ELD buffer size of 96 bytes and 854 + * the HDA codec driver will check that each byte read from the buffer 855 + * is valid. Therefore every byte must be written, even if no 96 bytes 856 + * were parsed from EDID. 857 + */ 858 + for (i = length; i < HDMI_ELD_BUFFER_SIZE; i++) 859 + tegra_hdmi_writel(hdmi, i << 8 | 0, 860 + HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 861 + 862 + value = SOR_AUDIO_HDA_PRESENSE_VALID | SOR_AUDIO_HDA_PRESENSE_PRESENT; 863 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE); 939 864 } 940 865 941 866 static void tegra_hdmi_encoder_enable(struct drm_encoder *encoder) ··· 976 837 unsigned int h_sync_width, h_front_porch, h_back_porch, i, rekey; 977 838 struct tegra_output *output = encoder_to_output(encoder); 978 839 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 979 - struct device_node *node = output->dev->of_node; 980 840 struct tegra_hdmi *hdmi = to_hdmi(output); 981 - unsigned int pulse_start, div82, pclk; 841 + unsigned int pulse_start, div82; 982 842 int retries = 1000; 983 843 u32 value; 984 844 int err; 985 845 986 - hdmi->dvi = !tegra_output_is_hdmi(output); 987 - 988 - pclk = mode->clock * 1000; 846 + hdmi->pixel_clock = mode->clock * 1000; 989 847 h_sync_width = mode->hsync_end - mode->hsync_start; 990 848 h_back_porch = mode->htotal - mode->hsync_end; 991 849 h_front_porch = mode->hsync_start - mode->hdisplay; 992 850 993 - err = clk_set_rate(hdmi->clk, pclk); 851 + err = clk_set_rate(hdmi->clk, hdmi->pixel_clock); 994 852 if (err < 0) { 995 853 dev_err(hdmi->dev, "failed to set HDMI clock frequency: %d\n", 996 854 err); ··· 1046 910 value = SOR_REFCLK_DIV_INT(div82 >> 2) | SOR_REFCLK_DIV_FRAC(div82); 1047 911 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_REFCLK); 1048 912 913 + hdmi->dvi = !tegra_output_is_hdmi(output); 1049 914 if (!hdmi->dvi) { 1050 - err = tegra_hdmi_setup_audio(hdmi, pclk); 915 + err = tegra_hdmi_setup_audio(hdmi); 1051 916 if (err < 0) 1052 917 hdmi->dvi = true; 1053 918 } 1054 919 1055 - if (of_device_is_compatible(node, "nvidia,tegra20-hdmi")) { 1056 - /* 1057 - * TODO: add ELD support 1058 - */ 1059 - } 920 + if (hdmi->config->has_hda) 921 + tegra_hdmi_write_eld(hdmi); 1060 922 1061 923 rekey = HDMI_REKEY_DEFAULT; 1062 924 value = HDMI_CTRL_REKEY(rekey); ··· 1066 932 1067 933 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_CTRL); 1068 934 1069 - if (hdmi->dvi) 1070 - tegra_hdmi_writel(hdmi, 0x0, 1071 - HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 1072 - else 1073 - tegra_hdmi_writel(hdmi, GENERIC_CTRL_AUDIO, 1074 - HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 935 + if (!hdmi->dvi) { 936 + tegra_hdmi_setup_avi_infoframe(hdmi, mode); 937 + tegra_hdmi_setup_audio_infoframe(hdmi); 1075 938 1076 - tegra_hdmi_setup_avi_infoframe(hdmi, mode); 1077 - tegra_hdmi_setup_audio_infoframe(hdmi); 1078 - tegra_hdmi_setup_stereo_infoframe(hdmi); 939 + if (hdmi->stereo) 940 + tegra_hdmi_setup_stereo_infoframe(hdmi); 941 + } 1079 942 1080 943 /* TMDS CONFIG */ 1081 944 for (i = 0; i < hdmi->config->num_tmds; i++) { 1082 - if (pclk <= hdmi->config->tmds[i].pclk) { 945 + if (hdmi->pixel_clock <= hdmi->config->tmds[i].pclk) { 1083 946 tegra_hdmi_setup_tmds(hdmi, &hdmi->config->tmds[i]); 1084 947 break; 1085 948 } ··· 1162 1031 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 1163 1032 1164 1033 tegra_dc_commit(dc); 1034 + 1035 + if (!hdmi->dvi) { 1036 + tegra_hdmi_enable_avi_infoframe(hdmi); 1037 + tegra_hdmi_enable_audio_infoframe(hdmi); 1038 + tegra_hdmi_enable_audio(hdmi); 1039 + 1040 + if (hdmi->stereo) 1041 + tegra_hdmi_enable_stereo_infoframe(hdmi); 1042 + } 1165 1043 1166 1044 /* TODO: add HDCP support */ 1167 1045 } ··· 1376 1236 DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG); 1377 1237 DUMP_REG(HDMI_NV_PDISP_KEY_SKEY_INDEX); 1378 1238 DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0); 1239 + DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_SPARE0); 1240 + DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0); 1241 + DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH1); 1379 1242 DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 1380 1243 DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE); 1244 + DUMP_REG(HDMI_NV_PDISP_INT_STATUS); 1245 + DUMP_REG(HDMI_NV_PDISP_INT_MASK); 1246 + DUMP_REG(HDMI_NV_PDISP_INT_ENABLE); 1381 1247 DUMP_REG(HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT); 1382 1248 1383 1249 #undef DUMP_REG ··· 1515 1369 1516 1370 reset_control_deassert(hdmi->rst); 1517 1371 1372 + /* 1373 + * Enable and unmask the HDA codec SCRATCH0 register interrupt. This 1374 + * is used for interoperability between the HDA codec driver and the 1375 + * HDMI driver. 1376 + */ 1377 + tegra_hdmi_writel(hdmi, INT_CODEC_SCRATCH0, HDMI_NV_PDISP_INT_ENABLE); 1378 + tegra_hdmi_writel(hdmi, INT_CODEC_SCRATCH0, HDMI_NV_PDISP_INT_MASK); 1379 + 1518 1380 return 0; 1519 1381 } 1520 1382 1521 1383 static int tegra_hdmi_exit(struct host1x_client *client) 1522 1384 { 1523 1385 struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); 1386 + 1387 + tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_MASK); 1388 + tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_ENABLE); 1524 1389 1525 1390 tegra_output_exit(&hdmi->output); 1526 1391 ··· 1559 1402 .fuse_override_offset = HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT, 1560 1403 .fuse_override_value = 1 << 31, 1561 1404 .has_sor_io_peak_current = false, 1405 + .has_hda = false, 1406 + .has_hbr = false, 1562 1407 }; 1563 1408 1564 1409 static const struct tegra_hdmi_config tegra30_hdmi_config = { ··· 1569 1410 .fuse_override_offset = HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT, 1570 1411 .fuse_override_value = 1 << 31, 1571 1412 .has_sor_io_peak_current = false, 1413 + .has_hda = true, 1414 + .has_hbr = false, 1572 1415 }; 1573 1416 1574 1417 static const struct tegra_hdmi_config tegra114_hdmi_config = { ··· 1579 1418 .fuse_override_offset = HDMI_NV_PDISP_SOR_PAD_CTLS0, 1580 1419 .fuse_override_value = 1 << 31, 1581 1420 .has_sor_io_peak_current = true, 1421 + .has_hda = true, 1422 + .has_hbr = true, 1582 1423 }; 1583 1424 1584 1425 static const struct tegra_hdmi_config tegra124_hdmi_config = { ··· 1589 1426 .fuse_override_offset = HDMI_NV_PDISP_SOR_PAD_CTLS0, 1590 1427 .fuse_override_value = 1 << 31, 1591 1428 .has_sor_io_peak_current = true, 1429 + .has_hda = true, 1430 + .has_hbr = true, 1592 1431 }; 1593 1432 1594 1433 static const struct of_device_id tegra_hdmi_of_match[] = { ··· 1601 1436 { }, 1602 1437 }; 1603 1438 MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match); 1439 + 1440 + static void hda_format_parse(unsigned int format, unsigned int *rate, 1441 + unsigned int *channels) 1442 + { 1443 + unsigned int mul, div; 1444 + 1445 + if (format & AC_FMT_BASE_44K) 1446 + *rate = 44100; 1447 + else 1448 + *rate = 48000; 1449 + 1450 + mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT; 1451 + div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT; 1452 + 1453 + *rate = *rate * (mul + 1) / (div + 1); 1454 + 1455 + *channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT; 1456 + } 1457 + 1458 + static irqreturn_t tegra_hdmi_irq(int irq, void *data) 1459 + { 1460 + struct tegra_hdmi *hdmi = data; 1461 + u32 value; 1462 + int err; 1463 + 1464 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_INT_STATUS); 1465 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_INT_STATUS); 1466 + 1467 + if (value & INT_CODEC_SCRATCH0) { 1468 + unsigned int format; 1469 + u32 value; 1470 + 1471 + value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0); 1472 + 1473 + if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) { 1474 + unsigned int sample_rate, channels; 1475 + 1476 + format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK; 1477 + 1478 + hda_format_parse(format, &sample_rate, &channels); 1479 + 1480 + hdmi->audio_sample_rate = sample_rate; 1481 + hdmi->audio_channels = channels; 1482 + 1483 + err = tegra_hdmi_setup_audio(hdmi); 1484 + if (err < 0) { 1485 + tegra_hdmi_disable_audio_infoframe(hdmi); 1486 + tegra_hdmi_disable_audio(hdmi); 1487 + } else { 1488 + tegra_hdmi_setup_audio_infoframe(hdmi); 1489 + tegra_hdmi_enable_audio_infoframe(hdmi); 1490 + tegra_hdmi_enable_audio(hdmi); 1491 + } 1492 + } else { 1493 + tegra_hdmi_disable_audio_infoframe(hdmi); 1494 + tegra_hdmi_disable_audio(hdmi); 1495 + } 1496 + } 1497 + 1498 + return IRQ_HANDLED; 1499 + } 1604 1500 1605 1501 static int tegra_hdmi_probe(struct platform_device *pdev) 1606 1502 { ··· 1680 1454 1681 1455 hdmi->config = match->data; 1682 1456 hdmi->dev = &pdev->dev; 1457 + 1683 1458 hdmi->audio_source = AUTO; 1684 - hdmi->audio_freq = 44100; 1459 + hdmi->audio_sample_rate = 48000; 1460 + hdmi->audio_channels = 2; 1685 1461 hdmi->stereo = false; 1686 1462 hdmi->dvi = false; 1687 1463 ··· 1743 1515 return err; 1744 1516 1745 1517 hdmi->irq = err; 1518 + 1519 + err = devm_request_irq(hdmi->dev, hdmi->irq, tegra_hdmi_irq, 0, 1520 + dev_name(hdmi->dev), hdmi); 1521 + if (err < 0) { 1522 + dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", 1523 + hdmi->irq, err); 1524 + return err; 1525 + } 1746 1526 1747 1527 INIT_LIST_HEAD(&hdmi->client.list); 1748 1528 hdmi->client.ops = &hdmi_client_ops;
+20 -1
drivers/gpu/drm/tegra/hdmi.h
··· 468 468 #define HDMI_NV_PDISP_KEY_SKEY_INDEX 0xa3 469 469 470 470 #define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0 0xac 471 - #define AUDIO_CNTRL0_INJECT_NULLSMPL (1 << 29) 471 + #define SOR_AUDIO_CNTRL0_SOURCE_SELECT_AUTO (0 << 20) 472 + #define SOR_AUDIO_CNTRL0_SOURCE_SELECT_SPDIF (1 << 20) 473 + #define SOR_AUDIO_CNTRL0_SOURCE_SELECT_HDAL (2 << 20) 474 + #define SOR_AUDIO_CNTRL0_INJECT_NULLSMPL (1 << 29) 475 + #define HDMI_NV_PDISP_SOR_AUDIO_SPARE0 0xae 476 + #define SOR_AUDIO_SPARE0_HBR_ENABLE (1 << 27) 477 + #define HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0 0xba 478 + #define SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID (1 << 30) 479 + #define SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK 0xffff 480 + #define HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH1 0xbb 472 481 #define HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR 0xbc 473 482 #define HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE 0xbd 483 + #define SOR_AUDIO_HDA_PRESENSE_VALID (1 << 1) 484 + #define SOR_AUDIO_HDA_PRESENSE_PRESENT (1 << 0) 474 485 475 486 #define HDMI_NV_PDISP_SOR_AUDIO_AVAL_0320 0xbf 476 487 #define HDMI_NV_PDISP_SOR_AUDIO_AVAL_0441 0xc0 ··· 491 480 #define HDMI_NV_PDISP_SOR_AUDIO_AVAL_0960 0xc4 492 481 #define HDMI_NV_PDISP_SOR_AUDIO_AVAL_1920 0xc5 493 482 #define HDMI_NV_PDISP_SOR_AUDIO_AVAL_DEFAULT 0xc5 483 + 484 + #define HDMI_NV_PDISP_INT_STATUS 0xcc 485 + #define INT_SCRATCH (1 << 3) 486 + #define INT_CP_REQUEST (1 << 2) 487 + #define INT_CODEC_SCRATCH1 (1 << 1) 488 + #define INT_CODEC_SCRATCH0 (1 << 0) 489 + #define HDMI_NV_PDISP_INT_MASK 0xcd 490 + #define HDMI_NV_PDISP_INT_ENABLE 0xce 494 491 495 492 #define HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT 0xd1 496 493 #define PEAK_CURRENT_LANE0(x) (((x) & 0x7f) << 0)
+1
drivers/gpu/drm/tegra/output.c
··· 36 36 37 37 if (edid) { 38 38 err = drm_add_edid_modes(connector, edid); 39 + drm_edid_to_eld(connector, edid); 39 40 kfree(edid); 40 41 } 41 42