diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_hdmi.c')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 66 |
1 files changed, 26 insertions, 40 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a0e10aeb0e67..c021ddc1ffb4 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
| 35 | #include <linux/of.h> | 35 | #include <linux/of.h> |
| 36 | #include <linux/of_gpio.h> | 36 | #include <linux/of_gpio.h> |
| 37 | #include <linux/hdmi.h> | ||
| 37 | 38 | ||
| 38 | #include <drm/exynos_drm.h> | 39 | #include <drm/exynos_drm.h> |
| 39 | 40 | ||
| @@ -59,19 +60,6 @@ | |||
| 59 | #define HDMI_AUI_VERSION 0x01 | 60 | #define HDMI_AUI_VERSION 0x01 |
| 60 | #define HDMI_AUI_LENGTH 0x0A | 61 | #define HDMI_AUI_LENGTH 0x0A |
| 61 | 62 | ||
| 62 | /* HDMI infoframe to configure HDMI out packet header, AUI and AVI */ | ||
| 63 | enum HDMI_PACKET_TYPE { | ||
| 64 | /* refer to Table 5-8 Packet Type in HDMI specification v1.4a */ | ||
| 65 | /* InfoFrame packet type */ | ||
| 66 | HDMI_PACKET_TYPE_INFOFRAME = 0x80, | ||
| 67 | /* Vendor-Specific InfoFrame */ | ||
| 68 | HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1, | ||
| 69 | /* Auxiliary Video information InfoFrame */ | ||
| 70 | HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2, | ||
| 71 | /* Audio information InfoFrame */ | ||
| 72 | HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4 | ||
| 73 | }; | ||
| 74 | |||
| 75 | enum hdmi_type { | 63 | enum hdmi_type { |
| 76 | HDMI_TYPE13, | 64 | HDMI_TYPE13, |
| 77 | HDMI_TYPE14, | 65 | HDMI_TYPE14, |
| @@ -379,12 +367,6 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = { | |||
| 379 | }, | 367 | }, |
| 380 | }; | 368 | }; |
| 381 | 369 | ||
| 382 | struct hdmi_infoframe { | ||
| 383 | enum HDMI_PACKET_TYPE type; | ||
| 384 | u8 ver; | ||
| 385 | u8 len; | ||
| 386 | }; | ||
| 387 | |||
| 388 | static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) | 370 | static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) |
| 389 | { | 371 | { |
| 390 | return readl(hdata->regs + reg_id); | 372 | return readl(hdata->regs + reg_id); |
| @@ -682,7 +664,7 @@ static u8 hdmi_chksum(struct hdmi_context *hdata, | |||
| 682 | } | 664 | } |
| 683 | 665 | ||
| 684 | static void hdmi_reg_infoframe(struct hdmi_context *hdata, | 666 | static void hdmi_reg_infoframe(struct hdmi_context *hdata, |
| 685 | struct hdmi_infoframe *infoframe) | 667 | union hdmi_infoframe *infoframe) |
| 686 | { | 668 | { |
| 687 | u32 hdr_sum; | 669 | u32 hdr_sum; |
| 688 | u8 chksum; | 670 | u8 chksum; |
| @@ -700,13 +682,15 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, | |||
| 700 | return; | 682 | return; |
| 701 | } | 683 | } |
| 702 | 684 | ||
| 703 | switch (infoframe->type) { | 685 | switch (infoframe->any.type) { |
| 704 | case HDMI_PACKET_TYPE_AVI: | 686 | case HDMI_INFOFRAME_TYPE_AVI: |
| 705 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); | 687 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); |
| 706 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type); | 688 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type); |
| 707 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver); | 689 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, |
| 708 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len); | 690 | infoframe->any.version); |
| 709 | hdr_sum = infoframe->type + infoframe->ver + infoframe->len; | 691 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length); |
| 692 | hdr_sum = infoframe->any.type + infoframe->any.version + | ||
| 693 | infoframe->any.length; | ||
| 710 | 694 | ||
| 711 | /* Output format zero hardcoded ,RGB YBCR selection */ | 695 | /* Output format zero hardcoded ,RGB YBCR selection */ |
| 712 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | | 696 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | |
| @@ -722,18 +706,20 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, | |||
| 722 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); | 706 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); |
| 723 | 707 | ||
| 724 | chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), | 708 | chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), |
| 725 | infoframe->len, hdr_sum); | 709 | infoframe->any.length, hdr_sum); |
| 726 | DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); | 710 | DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); |
| 727 | hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); | 711 | hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); |
| 728 | break; | 712 | break; |
| 729 | case HDMI_PACKET_TYPE_AUI: | 713 | case HDMI_INFOFRAME_TYPE_AUDIO: |
| 730 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); | 714 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); |
| 731 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type); | 715 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type); |
| 732 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver); | 716 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, |
| 733 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len); | 717 | infoframe->any.version); |
| 734 | hdr_sum = infoframe->type + infoframe->ver + infoframe->len; | 718 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length); |
| 719 | hdr_sum = infoframe->any.type + infoframe->any.version + | ||
| 720 | infoframe->any.length; | ||
| 735 | chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), | 721 | chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), |
| 736 | infoframe->len, hdr_sum); | 722 | infoframe->any.length, hdr_sum); |
| 737 | DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); | 723 | DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); |
| 738 | hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); | 724 | hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); |
| 739 | break; | 725 | break; |
| @@ -985,7 +971,7 @@ static void hdmi_conf_reset(struct hdmi_context *hdata) | |||
| 985 | 971 | ||
| 986 | static void hdmi_conf_init(struct hdmi_context *hdata) | 972 | static void hdmi_conf_init(struct hdmi_context *hdata) |
| 987 | { | 973 | { |
| 988 | struct hdmi_infoframe infoframe; | 974 | union hdmi_infoframe infoframe; |
| 989 | 975 | ||
| 990 | /* disable HPD interrupts from HDMI IP block, use GPIO instead */ | 976 | /* disable HPD interrupts from HDMI IP block, use GPIO instead */ |
| 991 | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | | 977 | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | |
| @@ -1021,14 +1007,14 @@ static void hdmi_conf_init(struct hdmi_context *hdata) | |||
| 1021 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); | 1007 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); |
| 1022 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); | 1008 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); |
| 1023 | } else { | 1009 | } else { |
| 1024 | infoframe.type = HDMI_PACKET_TYPE_AVI; | 1010 | infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI; |
| 1025 | infoframe.ver = HDMI_AVI_VERSION; | 1011 | infoframe.any.version = HDMI_AVI_VERSION; |
| 1026 | infoframe.len = HDMI_AVI_LENGTH; | 1012 | infoframe.any.length = HDMI_AVI_LENGTH; |
| 1027 | hdmi_reg_infoframe(hdata, &infoframe); | 1013 | hdmi_reg_infoframe(hdata, &infoframe); |
| 1028 | 1014 | ||
| 1029 | infoframe.type = HDMI_PACKET_TYPE_AUI; | 1015 | infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO; |
| 1030 | infoframe.ver = HDMI_AUI_VERSION; | 1016 | infoframe.any.version = HDMI_AUI_VERSION; |
| 1031 | infoframe.len = HDMI_AUI_LENGTH; | 1017 | infoframe.any.length = HDMI_AUI_LENGTH; |
| 1032 | hdmi_reg_infoframe(hdata, &infoframe); | 1018 | hdmi_reg_infoframe(hdata, &infoframe); |
| 1033 | 1019 | ||
| 1034 | /* enable AVI packet every vsync, fixes purple line problem */ | 1020 | /* enable AVI packet every vsync, fixes purple line problem */ |
