From 9898083fa2841a73227515cbe2659c99f353db95 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 24 Apr 2012 18:10:25 -0300 Subject: [PATCH] intel_infoframes: add support for Gen 4 Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- man/intel_infoframes.man | 2 +- tools/intel_infoframes.c | 200 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 147 insertions(+), 55 deletions(-) diff --git a/man/intel_infoframes.man b/man/intel_infoframes.man index c20d4b4..b015949 100644 --- a/man/intel_infoframes.man +++ b/man/intel_infoframes.man @@ -20,7 +20,7 @@ or .B --help options to learn how to use the command .SH LIMITATIONS -Not all HDMI monitors respect the InfoFrames sent to them. Only Iron Lake +Not all HDMI monitors respect the InfoFrames sent to them. Only GEN 4 or newer hardware is supported yet. .SH SEE ALSO HDMI specification, CEA-861 specification. diff --git a/tools/intel_infoframes.c b/tools/intel_infoframes.c index 0aec79a..57d01a8 100644 --- a/tools/intel_infoframes.c +++ b/tools/intel_infoframes.c @@ -40,15 +40,19 @@ typedef enum { } Transcoder; typedef enum { - REG_HDMIB = 0xe1140, - REG_HDMIC = 0xe1150, - REG_HDMID = 0xe1160, - REG_DIP_CTL_A = 0xe0200, - REG_DIP_CTL_B = 0xe1200, - REG_DIP_CTL_C = 0xe2200, - REG_DIP_DATA_A = 0xe0208, - REG_DIP_DATA_B = 0xe1208, - REG_DIP_DATA_C = 0xe2208, + REG_HDMIB_GEN4 = 0x61140, + REG_HDMIC_GEN4 = 0x61160, + REG_HDMIB_PCH = 0xe1140, + REG_HDMIC_PCH = 0xe1150, + REG_HDMID_PCH = 0xe1160, + REG_DIP_CTL_GEN4 = 0x61170, + REG_DIP_CTL_A = 0xe0200, + REG_DIP_CTL_B = 0xe1200, + REG_DIP_CTL_C = 0xe2200, + REG_DIP_DATA_GEN4 = 0x61178, + REG_DIP_DATA_A = 0xe0208, + REG_DIP_DATA_B = 0xe1208, + REG_DIP_DATA_C = 0xe2208, } Register; typedef enum { @@ -82,13 +86,14 @@ typedef enum { SOURCE_DEVICE_RESERVED = 0x0c } SourceDevice; -#define HDMI_PORT_ENABLE (1 << 31) -#define HDMI_PORT_TRANSCODER_IBX (1 << 30) -#define HDMI_PORT_TRANSCODER_CPT (3 << 29) -#define HDMI_PORT_ENCODING (3 << 10) -#define HDMI_PORT_MODE (1 << 9) -#define HDMI_PORT_AUDIO (1 << 6) -#define HDMI_PORT_DETECTED (1 << 2) +#define HDMI_PORT_ENABLE (1 << 31) +#define HDMI_PORT_TRANSCODER_GEN4 (1 << 30) +#define HDMI_PORT_TRANSCODER_IBX (1 << 30) +#define HDMI_PORT_TRANSCODER_CPT (3 << 29) +#define HDMI_PORT_ENCODING (3 << 10) +#define HDMI_PORT_MODE (1 << 9) +#define HDMI_PORT_AUDIO (1 << 6) +#define HDMI_PORT_DETECTED (1 << 2) #define DIP_CTL_ENABLE (1 << 31) #define DIP_CTL_GCP_ENABLE (1 << 25) @@ -108,6 +113,11 @@ typedef enum { #define DIP_CTL_BUFFER_SIZE (15 << 8) #define DIP_CTL_ACCESS_ADDR (15 << 0) +#define DIP_CTL_PORT_SEL_MASK_GEN4 (3 << 29) +#define DIP_CTL_PORT_SEL_B_GEN4 (1 << 29) +#define DIP_CTL_PORT_SEL_C_GEN4 (2 << 29) +#define DIP_CTL_BUFFER_TRANS_ACTIVE_GEN4 (1 << 28) + #define AVI_INFOFRAME_TYPE 0x82 #define AVI_INFOFRAME_VERSION 0x02 #define AVI_INFOFRAME_LENGTH 0x0d @@ -171,17 +181,21 @@ typedef union { uint32_t data32[16]; } DipInfoFrame; -Register hdmi_ports[] = { - REG_HDMIB, - REG_HDMIC, - REG_HDMID +Register gen4_hdmi_ports[] = { + REG_HDMIB_GEN4, + REG_HDMIC_GEN4, +}; +Register pch_hdmi_ports[] = { + REG_HDMIB_PCH, + REG_HDMIC_PCH, + REG_HDMID_PCH }; -Register dip_ctl_regs[] = { +Register pch_dip_ctl_regs[] = { REG_DIP_CTL_A, REG_DIP_CTL_B, REG_DIP_CTL_C }; -Register dip_data_regs[] = { +Register pch_dip_data_regs[] = { REG_DIP_DATA_A, REG_DIP_DATA_B, REG_DIP_DATA_C @@ -203,6 +217,8 @@ const char *dip_frequency_names[] = { "reserved (invalid)" }; +int gen = 0; + static const char *spd_source_to_string(SourceDevice source) { switch (source) { @@ -235,11 +251,37 @@ static const char *spd_source_to_string(SourceDevice source) } } +static Register get_dip_ctl_reg(Transcoder transcoder) +{ + if (gen == 4) + return REG_DIP_CTL_GEN4; + else + return pch_dip_ctl_regs[transcoder]; +} + +static Register get_dip_data_reg(Transcoder transcoder) +{ + if (gen == 4) + return REG_DIP_DATA_GEN4; + else + return pch_dip_data_regs[transcoder]; +} + +static Register get_hdmi_port(int hdmi_port_index) +{ + if (gen == 4) { + assert(hdmi_port_index <= 2); + return gen4_hdmi_ports[hdmi_port_index]; + } else { + return pch_hdmi_ports[hdmi_port_index]; + } +} + static void load_infoframe(Transcoder transcoder, DipInfoFrame *frame, DipType type) { - Register ctl_reg = dip_ctl_regs[transcoder]; - Register data_reg = dip_data_regs[transcoder]; + Register ctl_reg = get_dip_ctl_reg(transcoder); + Register data_reg = get_dip_data_reg(transcoder); uint32_t ctl_val; uint32_t i; @@ -290,21 +332,23 @@ static void infoframe_fix_checksum(DipInfoFrame *frame) static void dump_port_info(int hdmi_port_index) { - Register port = hdmi_ports[hdmi_port_index]; + Register port = get_hdmi_port(hdmi_port_index); uint32_t val = INREG(port); Transcoder transcoder; printf("\nPort %s:\n", hdmi_port_names[hdmi_port_index]); - printf("- %sdetected\n", val & HDMI_PORT_DETECTED ? "" : "not "); + printf("- %sdetected\n", val & HDMI_PORT_DETECTED ? "" : "not "); printf("- %s\n", val & HDMI_PORT_ENABLE ? "enabled" : "disabled"); if (!(val & HDMI_PORT_ENABLE)) return; - if (pch >= PCH_CPT) + if (gen == 4) + transcoder = (val & HDMI_PORT_TRANSCODER_GEN4) >> 30; + else if (pch >= PCH_CPT) transcoder = (val & HDMI_PORT_TRANSCODER_CPT) >> 29; else - transcoder = (val & HDMI_PORT_TRANSCODER_CPT) >> 30; + transcoder = (val & HDMI_PORT_TRANSCODER_IBX) >> 30; printf("- transcoder: %s\n", transcoder_names[transcoder]); switch ((val & HDMI_PORT_ENCODING) >> 10) { @@ -336,7 +380,7 @@ static void dump_raw_infoframe(DipInfoFrame *frame) static void dump_avi_info(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); DipFrequency freq; DipInfoFrame frame; @@ -346,6 +390,11 @@ static void dump_avi_info(Transcoder transcoder) printf("AVI InfoFrame:\n"); + if (gen == 4) { + printf("- %sbeing transmitted\n", + val & DIP_CTL_BUFFER_TRANS_ACTIVE_GEN4 ? "" : "not "); + } + freq = (val & DIP_CTL_FREQUENCY) >> 16; printf("- frequency: %s\n", dip_frequency_names[freq]); @@ -377,7 +426,7 @@ static void dump_avi_info(Transcoder transcoder) static void dump_vendor_info(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); DipFrequency freq; DipInfoFrame frame; @@ -387,6 +436,11 @@ static void dump_vendor_info(Transcoder transcoder) printf("Vendor InfoFrame:\n"); + if (gen == 4) { + printf("- %sbeing transmitted\n", + val & DIP_CTL_BUFFER_TRANS_ACTIVE_GEN4 ? "" : "not "); + } + freq = (val & DIP_CTL_FREQUENCY) >> 16; printf("- frequency: %s\n", dip_frequency_names[freq]); @@ -398,7 +452,7 @@ static void dump_vendor_info(Transcoder transcoder) static void dump_gamut_info(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); DipFrequency freq; DipInfoFrame frame; @@ -408,6 +462,11 @@ static void dump_gamut_info(Transcoder transcoder) printf("Gamut InfoFrame:\n"); + if (gen == 4) { + printf("- %sbeing transmitted\n", + val & DIP_CTL_BUFFER_TRANS_ACTIVE_GEN4 ? "" : "not "); + } + freq = (val & DIP_CTL_FREQUENCY) >> 16; printf("- frequency: %s\n", dip_frequency_names[freq]); @@ -419,7 +478,7 @@ static void dump_gamut_info(Transcoder transcoder) static void dump_spd_info(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); DipFrequency freq; DipInfoFrame frame; @@ -431,6 +490,11 @@ static void dump_spd_info(Transcoder transcoder) printf("SPD InfoFrame:\n"); + if (gen == 4) { + printf("- %sbeing transmitted\n", + val & DIP_CTL_BUFFER_TRANS_ACTIVE_GEN4 ? "" : "not "); + } + freq = (val & DIP_CTL_FREQUENCY) >> 16; printf("- frequency: %s\n", dip_frequency_names[freq]); @@ -456,10 +520,24 @@ static void dump_spd_info(Transcoder transcoder) static void dump_transcoder_info(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); - printf("\nTranscoder %s:\n", transcoder_names[transcoder]); + if (gen == 4) { + printf("\nDIP information:\n"); + switch (val & DIP_CTL_PORT_SEL_MASK_GEN4) { + case DIP_CTL_PORT_SEL_B_GEN4: + printf("- port B\n"); + break; + case DIP_CTL_PORT_SEL_C_GEN4: + printf("- port C\n"); + break; + default: + printf("- INVALID port!\n"); + } + } else { + printf("\nTranscoder %s:\n", transcoder_names[transcoder]); + } printf("- %s\n", val & DIP_CTL_ENABLE ? "enabled" : "disabled"); if (!(val & DIP_CTL_ENABLE)) return; @@ -481,17 +559,23 @@ static void dump_all_info(void) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(hdmi_ports); i++) - dump_port_info(i); - for (i = 0; i < ARRAY_SIZE(dip_ctl_regs); i++) - dump_transcoder_info(i); + if (gen == 4) { + for (i = 0; i < ARRAY_SIZE(gen4_hdmi_ports); i++) + dump_port_info(i); + dump_transcoder_info(0); + } else { + for (i = 0; i < ARRAY_SIZE(pch_hdmi_ports); i++) + dump_port_info(i); + for (i = 0; i < ARRAY_SIZE(pch_dip_ctl_regs); i++) + dump_transcoder_info(i); + } } static void write_infoframe(Transcoder transcoder, DipType type, DipInfoFrame *frame) { - Register ctl_reg = dip_ctl_regs[transcoder]; - Register data_reg = dip_data_regs[transcoder]; + Register ctl_reg = get_dip_ctl_reg(transcoder); + Register data_reg = get_dip_data_reg(transcoder); uint32_t ctl_val; unsigned int i; @@ -510,9 +594,9 @@ static void write_infoframe(Transcoder transcoder, DipType type, static void disable_infoframe(Transcoder transcoder, DipType type) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); - if (type == DIP_AVI) + if (gen != 4 && type == DIP_AVI) val &= ~DIP_CTL_ENABLE; val &= ~(1 << (21 + type)); OUTREG(reg, val); @@ -520,9 +604,9 @@ static void disable_infoframe(Transcoder transcoder, DipType type) static void enable_infoframe(Transcoder transcoder, DipType type) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); - if (type == DIP_AVI) + if (gen != 4 && type == DIP_AVI) val |= DIP_CTL_ENABLE; val |= (1 << (21 + type)); OUTREG(reg, val); @@ -575,7 +659,7 @@ static int parse_infoframe_option_s(const char *name, const char *s, static void change_avi_infoframe(Transcoder transcoder, char *commands) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); DipInfoFrame frame; char option[32]; @@ -675,7 +759,7 @@ static void change_avi_infoframe(Transcoder transcoder, char *commands) static void change_spd_infoframe(Transcoder transcoder, char *commands) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); DipInfoFrame frame; char option[16]; @@ -742,7 +826,7 @@ static void change_infoframe_checksum(Transcoder transcoder, DipType type, static void change_infoframe_frequency(Transcoder transcoder, DipType type, DipFrequency frequency) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); if (type == DIP_AVI && frequency != DIP_FREQ_EVERY_VSYNC) { @@ -757,7 +841,7 @@ static void change_infoframe_frequency(Transcoder transcoder, DipType type, static void disable_dip(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); val &= ~DIP_CTL_ENABLE; OUTREG(reg, val); @@ -765,7 +849,7 @@ static void disable_dip(Transcoder transcoder) static void enable_dip(Transcoder transcoder) { - Register reg = dip_ctl_regs[transcoder]; + Register reg = get_dip_ctl_reg(transcoder); uint32_t val = INREG(reg); val |= DIP_CTL_ENABLE; OUTREG(reg, val); @@ -908,8 +992,16 @@ int main(int argc, char *argv[]) intel_register_access_init(pci_dev, 0); intel_check_pch(); - if (!HAS_PCH_SPLIT(pci_dev->device_id)) { - printf("This program still only supports ILK or newer.\n"); + if (IS_GEN4(pci_dev->device_id)) + gen = 4; + else if (IS_GEN5(pci_dev->device_id)) + gen = 5; + else if (IS_GEN6(pci_dev->device_id)) + gen = 6; + else if (IS_GEN7(pci_dev->device_id)) + gen = 7; + else { + printf("This program does not support your hardware yet.\n"); ret = 1; goto out; } @@ -991,11 +1083,11 @@ int main(int argc, char *argv[]) case 'p': case 'P': if (!strcmp(optarg, "B")) - hdmi_port = REG_HDMIB; + hdmi_port = get_hdmi_port(0); else if (!strcmp(optarg, "C")) - hdmi_port = REG_HDMIC; + hdmi_port = get_hdmi_port(1); else if (!strcmp(optarg, "D")) - hdmi_port = REG_HDMID; + hdmi_port = get_hdmi_port(2); else { printf("Invalid HDMI port.\n"); ret = 1; -- 2.7.4