| /* |
| * drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_dump.c |
| * |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| */ |
| |
| #include <linux/module.h> |
| #include <linux/pwm.h> |
| #include <linux/list.h> |
| #include <linux/mutex.h> |
| #include <linux/err.h> |
| #include <linux/slab.h> |
| #include <linux/device.h> |
| #include <linux/debugfs.h> |
| #include <linux/seq_file.h> |
| #include <linux/amlogic/media/vout/hdmi_tx/hdmi_common.h> |
| #include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h> |
| #include "mach_reg.h" |
| #include "reg_ops.h" |
| #include "hdmi_tx_reg.h" |
| |
| #define PR_BUS(a) \ |
| do { \ |
| typeof(a) addr = (a); \ |
| seq_printf(s, "[%08x][%04x] = %08x\n", \ |
| TO_PHY_ADDR(addr), \ |
| (TO_PHY_ADDR(addr) & 0xffff) >> 2, \ |
| hd_read_reg(addr)); \ |
| } while (0) |
| |
| static inline unsigned int get_msr_cts(void); |
| |
| static int dump_regs_show(struct seq_file *s, void *p) |
| { |
| int i; |
| |
| if (!map) |
| return 0; |
| |
| if (map[PERIPHS_REG_IDX].phy_addr) { |
| seq_puts(s, "\n--------PERIPHS registers--------\n"); |
| for (i = 0; i < 0xff; i++) |
| PR_BUS(PERIPHS_REG_ADDR(i)); |
| } |
| |
| if (map[HHI_REG_IDX].phy_addr) { |
| seq_puts(s, "\n--------HHI registers--------\n"); |
| for (i = 0; i < 0x80; i++) |
| PR_BUS(HHI_REG_ADDR(i)); |
| for (i = 0x80; i < 0x100; i++) |
| PR_BUS(HHI_REG_ADDR(i)); |
| } |
| |
| if (map[VCBUS_REG_IDX].phy_addr) { |
| seq_puts(s, "\n--------ENCP registers--------\n"); |
| for (i = 0x1b00; i < 0x1b80; i++) |
| PR_BUS(VCBUS_REG_ADDR(i)); |
| for (i = 0x1b80; i < 0x1c00; i++) |
| PR_BUS(VCBUS_REG_ADDR(i)); |
| for (i = 0x1c00; i < 0x1c80; i++) |
| PR_BUS(VCBUS_REG_ADDR(i)); |
| for (i = 0x1c80; i < 0x1d00; i++) |
| PR_BUS(VCBUS_REG_ADDR(i)); |
| for (i = 0x2700; i < 0x2780; i++) |
| PR_BUS(VCBUS_REG_ADDR(i)); |
| for (i = 0x2780; i < 0x2800; i++) |
| PR_BUS(VCBUS_REG_ADDR(i)); |
| } |
| |
| if (map[CBUS_REG_IDX].phy_addr) { |
| seq_puts(s, "\n--------CBUS registers--------\n"); |
| PR_BUS(P_AIU_HDMI_CLK_DATA_CTRL); |
| PR_BUS(P_ISA_DEBUG_REG0); |
| } |
| |
| seq_puts(s, "\n"); |
| |
| return 0; |
| } |
| |
| static ssize_t dump_regs_write(struct file *file, const char __user *userbuf, |
| size_t count, loff_t *ppos) |
| { |
| /* TODO */ |
| return count; |
| } |
| |
| static int dump_regs_open(struct inode *inode, struct file *file) |
| { |
| return single_open(file, dump_regs_show, inode->i_private); |
| } |
| |
| static const struct file_operations dump_busreg_fops = { |
| .open = dump_regs_open, |
| .read = seq_read, |
| .write = dump_regs_write, |
| .release = single_release, |
| }; |
| |
| #define DUMP_SECTION(_a, _b) \ |
| do { \ |
| typeof(_a) a = (_a); \ |
| typeof(_b) b = (_b); \ |
| for (reg_adr = (a & ~SEC_OFFSET); \ |
| reg_adr < (b & ~SEC_OFFSET) + 1; reg_adr++) { \ |
| reg_val = hdmitx_rd_reg(reg_adr | SEC_OFFSET); \ |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); \ |
| } \ |
| } while (0) |
| |
| #define DUMP_HDCP_SECTION(_a, _b) \ |
| do { \ |
| typeof(_a) a = _a; \ |
| typeof(_b) b = _b; \ |
| for (reg_adr = (a & ~SEC_OFFSET); \ |
| reg_adr < (b & ~SEC_OFFSET) + 1; reg_adr++) { \ |
| hdmitx_wr_reg(HDMITX_DWC_A_KSVMEMCTRL, 0x1); \ |
| hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, 1 << 1, \ |
| 2 * HZ); \ |
| reg_val = hdmitx_rd_reg(reg_adr); \ |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); \ |
| } \ |
| } while (0) |
| |
| static int dump_hdmireg_show(struct seq_file *s, void *p) |
| { |
| unsigned int reg_val = 0; |
| unsigned int reg_adr = 0; |
| |
| seq_puts(s, "\n--------HDMITX registers--------\n"); |
| |
| DUMP_SECTION(HDMITX_TOP_SW_RESET, HDMITX_TOP_HDCP22_MIN_SIZE); |
| if (0) |
| DUMP_HDCP_SECTION(HDMITX_DWC_HDCP_BSTATUS_0, |
| HDMITX_DWC_HDCP_REVOC_LIST_END); |
| DUMP_SECTION(HDMITX_DWC_DESIGN_ID, HDMITX_DWC_CONFIG3_ID); |
| DUMP_SECTION(HDMITX_DWC_IH_FC_STAT0, HDMITX_DWC_IH_MUTE); |
| DUMP_SECTION(HDMITX_DWC_TX_INVID0, HDMITX_DWC_TX_BCBDATA1); |
| DUMP_SECTION(HDMITX_DWC_VP_STATUS, HDMITX_DWC_VP_MASK); |
| DUMP_SECTION(HDMITX_DWC_FC_INVIDCONF, HDMITX_DWC_FC_DBGTMDS2); |
| DUMP_SECTION(HDMITX_DWC_PHY_CONF0, HDMITX_DWC_I2CM_PHY_SDA_HOLD); |
| DUMP_SECTION(HDMITX_DWC_AUD_CONF0, HDMITX_DWC_AUD_INT1); |
| DUMP_SECTION(HDMITX_DWC_AUD_N1, HDMITX_DWC_AUD_INPUTCLKFS); |
| DUMP_SECTION(HDMITX_DWC_AUD_SPDIF0, HDMITX_DWC_AUD_SPDIFINT1); |
| DUMP_SECTION(HDMITX_DWC_MC_CLKDIS, HDMITX_DWC_MC_LOCKONCLOCK); |
| DUMP_SECTION(HDMITX_DWC_CSC_CFG, HDMITX_DWC_CSC_LIMIT_DN_LSB); |
| DUMP_SECTION(HDMITX_DWC_A_HDCPCFG0, HDMITX_DWC_A_BSTATUS_LO); |
| DUMP_SECTION(HDMITX_DWC_HDCPREG_BKSV0, HDMITX_DWC_HDCPREG_DPK6); |
| DUMP_SECTION(HDMITX_DWC_HDCP22REG_ID, HDMITX_DWC_HDCP22REG_MUTE); |
| DUMP_SECTION(HDMITX_DWC_CEC_CTRL, HDMITX_DWC_CEC_WAKEUPCTRL); |
| DUMP_SECTION(HDMITX_DWC_I2CM_SLAVE, HDMITX_DWC_I2CM_SCDC_UPDATE1); |
| return 0; |
| } |
| |
| static int dump_hdmireg_open(struct inode *inode, struct file *file) |
| { |
| return single_open(file, dump_hdmireg_show, inode->i_private); |
| } |
| |
| static const struct file_operations dump_hdmireg_fops = { |
| .open = dump_hdmireg_open, |
| .read = seq_read, |
| .release = single_release, |
| }; |
| |
| #define CONNECT2REG(_reg) ({ \ |
| typeof(_reg) reg = (_reg); \ |
| hdmitx_rd_reg(reg) + (hdmitx_rd_reg(reg + 1) << 8); }) |
| |
| static int dump_hdmitiming_show(struct seq_file *s, void *p) |
| { |
| unsigned int tmp = 0; |
| |
| seq_puts(s, "\n--------HDMITX timing--------\n"); |
| tmp = CONNECT2REG(HDMITX_DWC_FC_INHACTV0); |
| seq_printf(s, "Hactive = %d\n", tmp); |
| |
| tmp = CONNECT2REG(HDMITX_DWC_FC_INHBLANK0); |
| seq_printf(s, "Hblank = %d\n", tmp); |
| |
| tmp = CONNECT2REG(HDMITX_DWC_FC_INVACTV0); |
| seq_printf(s, "Vactive = %d\n", tmp); |
| |
| tmp = hdmitx_rd_reg(HDMITX_DWC_FC_INVBLANK); |
| seq_printf(s, "Vblank = %d\n", tmp); |
| |
| tmp = CONNECT2REG(HDMITX_DWC_FC_HSYNCINDELAY0); |
| seq_printf(s, "Hfront = %d\n", tmp); |
| |
| tmp = CONNECT2REG(HDMITX_DWC_FC_HSYNCINWIDTH0); |
| seq_printf(s, "Hsync = %d\n", tmp); |
| |
| tmp = hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINDELAY); |
| seq_printf(s, "Vfront = %d\n", tmp); |
| |
| tmp = hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINWIDTH); |
| seq_printf(s, "Vsync = %d\n", tmp); |
| |
| return 0; |
| } |
| |
| static int dump_hdmitiming_open(struct inode *inode, struct file *file) |
| { |
| return single_open(file, dump_hdmitiming_show, inode->i_private); |
| } |
| |
| static const struct file_operations dump_hdmitiming_fops = { |
| .open = dump_hdmitiming_open, |
| .read = seq_read, |
| .release = single_release, |
| }; |
| |
| static void hdmitx_parsing_avipkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| |
| seq_puts(s, "\n--------parsing AVIInfo--------\n"); |
| |
| if (hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 2)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "AVIInfo.enable: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AVICONF0; |
| reg_val = hdmitx_rd_reg(HDMITX_DWC_FC_AVICONF0); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch (reg_val & 0x3) { |
| case 0: |
| conf = "RGB"; |
| break; |
| case 1: |
| conf = "422"; |
| break; |
| case 2: |
| conf = "444"; |
| break; |
| case 3: |
| conf = "420"; |
| } |
| seq_printf(s, "colorspace: %s\n", conf); |
| |
| switch ((reg_val & 0x40) >> 6) { |
| case 0: |
| conf = "disable"; |
| break; |
| case 1: |
| conf = "enable"; |
| } |
| seq_printf(s, "active_format_present: %s\n", conf); |
| |
| switch ((reg_val & 0x0c) >> 2) { |
| case 0: |
| conf = "disable"; |
| break; |
| case 1: |
| conf = "vert bar"; |
| break; |
| case 2: |
| conf = "horiz bar"; |
| break; |
| case 3: |
| conf = "vert and horiz bar"; |
| } |
| seq_printf(s, "bar: %s\n", conf); |
| |
| switch ((reg_val & 0x30) >> 4) { |
| case 0: |
| conf = "disable"; |
| break; |
| case 1: |
| conf = "overscan"; |
| break; |
| case 2: |
| conf = "underscan"; |
| break; |
| default: |
| conf = "disable"; |
| } |
| seq_printf(s, "scan: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AVICONF1; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0xc0) >> 6) { |
| case 0: |
| conf = "disable"; |
| break; |
| case 1: |
| conf = "BT.601"; |
| break; |
| case 2: |
| conf = "BT.709"; |
| break; |
| case 3: |
| conf = "Extended"; |
| } |
| seq_printf(s, "colorimetry: %s\n", conf); |
| |
| switch ((reg_val & 0x30) >> 4) { |
| case 0: |
| conf = "disable"; |
| break; |
| case 1: |
| conf = "4:3"; |
| break; |
| case 2: |
| conf = "16:9"; |
| break; |
| default: |
| conf = "disable"; |
| } |
| seq_printf(s, "picture_aspect: %s\n", conf); |
| |
| switch (reg_val & 0xf) { |
| case 8: |
| conf = "Same as picture_aspect"; |
| break; |
| case 9: |
| conf = "4:3"; |
| break; |
| case 10: |
| conf = "16:9"; |
| break; |
| case 11: |
| conf = "14:9"; |
| break; |
| default: |
| conf = "Same as picture_aspect"; |
| } |
| seq_printf(s, "active_aspect: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AVICONF2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0x80) >> 7) { |
| case 0: |
| conf = "disable"; |
| break; |
| case 1: |
| conf = "enable"; |
| } |
| seq_printf(s, "itc: %s\n", conf); |
| |
| switch ((reg_val & 0x70) >> 4) { |
| case 0: |
| conf = "xvYCC601"; |
| break; |
| case 1: |
| conf = "xvYCC709"; |
| break; |
| case 2: |
| conf = "sYCC601"; |
| break; |
| case 3: |
| conf = "Adobe_YCC601"; |
| break; |
| case 4: |
| conf = "Adobe_RGB"; |
| break; |
| case 5: |
| case 6: |
| conf = "BT.2020"; |
| break; |
| default: |
| conf = "xvYCC601"; |
| } |
| seq_printf(s, "extended_colorimetriy: %s\n", conf); |
| |
| switch ((reg_val & 0xc) >> 2) { |
| case 0: |
| conf = "default"; |
| break; |
| case 1: |
| conf = "limited"; |
| break; |
| case 2: |
| conf = "full"; |
| break; |
| default: |
| conf = "default"; |
| } |
| seq_printf(s, "quantization_range: %s\n", conf); |
| |
| switch (reg_val & 0x3) { |
| case 0: |
| conf = "unknown"; |
| break; |
| case 1: |
| conf = "horiz"; |
| break; |
| case 2: |
| conf = "vert"; |
| break; |
| case 3: |
| conf = "horiz and vert"; |
| } |
| seq_printf(s, "nups: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AVIVID; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "vic: %d\n", reg_val); |
| |
| reg_adr = HDMITX_DWC_FC_AVICONF3; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch ((reg_val & 0xc) >> 2) { |
| case 0: |
| default: |
| conf = "limited"; |
| break; |
| case 1: |
| conf = "full"; |
| } |
| seq_printf(s, "ycc_quantization_range: %s\n", conf); |
| |
| switch (reg_val & 0x3) { |
| case 0: |
| conf = "graphics"; |
| break; |
| case 1: |
| conf = "photo"; |
| break; |
| case 2: |
| conf = "cinema"; |
| break; |
| case 3: |
| conf = "game"; |
| } |
| seq_printf(s, "content_type: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_PRCONF; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0xf0) >> 4) { |
| case 0: |
| case 1: |
| default: |
| conf = "no"; |
| break; |
| } |
| if (((reg_val & 0xf0) >> 4) < 2) |
| seq_printf(s, "pixel_repetition: %s\n", conf); |
| else |
| seq_printf(s, "pixel_repetition: %d times\n", |
| (reg_val & 0xf0) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_DATAUTO3; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0x8) >> 3) { |
| case 0: |
| conf = "RDRB"; |
| break; |
| case 1: |
| conf = "auto"; |
| } |
| seq_printf(s, "datauto: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_RDRB6; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "rdrb_interpolation: %d\n", reg_val & 0xf); |
| |
| reg_adr = HDMITX_DWC_FC_RDRB7; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "rdrb_perframe: %d\n", (reg_val & 0xf0) >> 4); |
| seq_printf(s, "rdrb_linespace: %d\n", reg_val & 0xf); |
| } |
| |
| static void hdmitx_parsing_spdpkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| unsigned char vend_name[9] = {0}; |
| unsigned char prod_name[17] = {0}; |
| int i; |
| |
| seq_puts(s, "\n--------parsing SPDInfo--------\n"); |
| |
| if (hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 4) || |
| hdmitx_get_bit(HDMITX_DWC_FC_DATAUTO0, 4)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "SPDInfo.enable: %s\n", conf); |
| |
| DUMP_SECTION(HDMITX_DWC_FC_SPDVENDORNAME0, |
| (HDMITX_DWC_FC_SPDVENDORNAME0 + 24)); |
| |
| for (i = 0; i < 8; i++) |
| vend_name[i] = hdmitx_rd_reg(HDMITX_DWC_FC_SPDVENDORNAME0 + i); |
| |
| for (i = 0; i < 16; i++) |
| prod_name[i] = hdmitx_rd_reg(HDMITX_DWC_FC_SPDVENDORNAME0 + |
| 8 + i); |
| |
| if (vend_name[0]) |
| seq_printf(s, "vendor name: %s\n", vend_name); |
| if (prod_name[0]) |
| seq_printf(s, "product description: %s\n", prod_name); |
| } |
| |
| static void hdmitx_parsing_audpkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| |
| seq_puts(s, "\n--------parsing AudioInfo--------\n"); |
| |
| if (hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 3)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "AudioInfo.enable: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AUDICONF0; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch (reg_val & 0xf) { |
| case CT_REFER_TO_STREAM: |
| conf = "refer to stream header"; |
| break; |
| case CT_PCM: |
| conf = "L-PCM"; |
| break; |
| case CT_AC_3: |
| conf = "AC-3"; |
| break; |
| case CT_MPEG1: |
| conf = "MPEG1"; |
| break; |
| case CT_MP3: |
| conf = "MP3"; |
| break; |
| case CT_MPEG2: |
| conf = "MPEG2"; |
| break; |
| case CT_AAC: |
| conf = "AAC"; |
| break; |
| case CT_DTS: |
| conf = "DTS"; |
| break; |
| case CT_ATRAC: |
| conf = "ATRAC"; |
| break; |
| case CT_ONE_BIT_AUDIO: |
| conf = "One Bit Audio"; |
| break; |
| case CT_DOLBY_D: |
| conf = "Dobly Digital+"; |
| break; |
| case CT_DTS_HD: |
| conf = "DTS_HD"; |
| break; |
| case CT_MAT: |
| conf = "MAT"; |
| break; |
| case CT_DST: |
| conf = "DST"; |
| break; |
| case CT_WMA: |
| conf = "WMA"; |
| break; |
| default: |
| conf = "MAX"; |
| } |
| seq_printf(s, "coding_type: %s\n", conf); |
| |
| switch ((reg_val & 0x70) >> 4) { |
| case CC_REFER_TO_STREAM: |
| conf = "refer to stream header"; |
| break; |
| case CC_2CH: |
| conf = "2 channels"; |
| break; |
| case CC_3CH: |
| conf = "3 channels"; |
| break; |
| case CC_4CH: |
| conf = "4 channels"; |
| break; |
| case CC_5CH: |
| conf = "5 channels"; |
| break; |
| case CC_6CH: |
| conf = "6 channels"; |
| break; |
| case CC_7CH: |
| conf = "7 channels"; |
| break; |
| case CC_8CH: |
| conf = "8 channels"; |
| break; |
| default: |
| conf = "MAX"; |
| } |
| seq_printf(s, "channel_count: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AUDICONF1; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch (reg_val & 0x7) { |
| case FS_REFER_TO_STREAM: |
| conf = "refer to stream header"; |
| break; |
| case FS_32K: |
| conf = "32kHz"; |
| break; |
| case FS_44K1: |
| conf = "44.1kHz"; |
| break; |
| case FS_48K: |
| conf = "48kHz"; |
| break; |
| case FS_88K2: |
| conf = "88.2kHz"; |
| break; |
| case FS_96K: |
| conf = "96kHz"; |
| break; |
| case FS_176K4: |
| conf = "176.4kHz"; |
| break; |
| case FS_192K: |
| conf = "192kHz"; |
| } |
| seq_printf(s, "sample_frequency: %s\n", conf); |
| |
| switch ((reg_val & 0x30) >> 4) { |
| case SS_REFER_TO_STREAM: |
| conf = "refer to stream header"; |
| break; |
| case SS_16BITS: |
| conf = "16bit"; |
| break; |
| case SS_20BITS: |
| conf = "20bit"; |
| break; |
| case SS_24BITS: |
| conf = "24bit"; |
| break; |
| default: |
| conf = "MAX"; |
| } |
| seq_printf(s, "sample_size: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_AUDICONF2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "channel_allocation: %d\n", reg_val); |
| |
| reg_adr = HDMITX_DWC_FC_AUDICONF3; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "level_shift_value: %d\n", reg_val & 0xf); |
| seq_printf(s, "down_mix_enable: %d\n", (reg_val & 0x10) >> 4); |
| seq_printf(s, "LFE_playback_info: %d\n", (reg_val & 0x60) >> 5); |
| |
| reg_adr = HDMITX_DWC_FC_DATAUTO3; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0x2) >> 1) { |
| case 0: |
| conf = "RDRB"; |
| break; |
| case 1: |
| conf = "auto"; |
| } |
| seq_printf(s, "datauto: %s\n", conf); |
| } |
| |
| static void hdmitx_parsing_gcppkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| |
| seq_puts(s, "\n--------parsing GCP--------\n"); |
| |
| if (hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 1)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| |
| seq_printf(s, "GCP.enable: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_GCP; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "clear_avmute: %d\n", reg_val & 0x1); |
| seq_printf(s, "set_avmute: %d\n", (reg_val & 0x2) >> 1); |
| seq_printf(s, "default_phase: %d\n", (reg_val & 0x4) >> 2); |
| |
| reg_adr = HDMITX_DWC_VP_STATUS; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "packing_phase: %d\n", reg_val & 0xf); |
| |
| reg_adr = HDMITX_DWC_VP_PR_CD; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0xf0) >> 4) { |
| case 0: |
| case 4: |
| conf = "24bit"; |
| break; |
| case 5: |
| conf = "30bit"; |
| break; |
| case 6: |
| conf = "36bit"; |
| break; |
| case 7: |
| conf = "48bit"; |
| break; |
| default: |
| conf = "reserved"; |
| } |
| seq_printf(s, "color_depth: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_VP_REMAP; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch (reg_val & 0x3) { |
| case 0: |
| conf = "16bit"; |
| break; |
| case 1: |
| conf = "20bit"; |
| break; |
| case 2: |
| conf = "24bit"; |
| break; |
| default: |
| conf = "reserved"; |
| } |
| seq_printf(s, "YCC 422 size: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_VP_CONF; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch (reg_val & 0x3) { |
| case 0: |
| conf = "pixel_packing"; |
| break; |
| case 1: |
| conf = "YCC 422"; |
| break; |
| case 2: |
| case 3: |
| conf = "8bit bypass"; |
| } |
| seq_printf(s, "output selector: %s\n", conf); |
| seq_printf(s, "bypass select: %d\n", (reg_val & 0x4) >> 2); |
| seq_printf(s, "YCC 422 enable: %d\n", (reg_val & 0x8) >> 3); |
| seq_printf(s, "pixel repeater enable: %d\n", (reg_val & 0x10) >> 4); |
| seq_printf(s, "pixel packing enable: %d\n", (reg_val & 0x20) >> 5); |
| seq_printf(s, "bypass enable: %d\n", (reg_val & 0x40) >> 6); |
| |
| reg_adr = HDMITX_DWC_FC_DATAUTO3; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| switch ((reg_val & 0x4) >> 2) { |
| case 0: |
| conf = "RDRB"; |
| break; |
| case 1: |
| conf = "auto"; |
| } |
| seq_printf(s, "datauto mode: %s\n", conf); |
| } |
| |
| static void hdmitx_parsing_acrpkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| unsigned int n = 0; |
| |
| seq_puts(s, "\n--------parsing ACR--------\n"); |
| |
| if (hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 1)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "ACR.enable: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_AUD_INPUTCLKFS; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch (reg_val & 0x7) { |
| case 0: |
| conf = "128xFs"; |
| break; |
| case 1: |
| conf = "512xFs"; |
| break; |
| case 4: |
| conf = "64xFs"; |
| break; |
| default: |
| conf = "reserved"; |
| } |
| seq_printf(s, "ifsfactor: %s\n", conf); |
| |
| n = hdmitx_rd_reg(HDMITX_DWC_AUD_N1) + |
| (hdmitx_rd_reg(HDMITX_DWC_AUD_N2) << 8) + |
| ((hdmitx_rd_reg(HDMITX_DWC_AUD_N3) & 0xf) << 16); |
| seq_printf(s, "N: %d\n", n); |
| |
| reg_val = hdmitx_get_bit(HDMITX_DWC_AUD_N3, 7); |
| seq_printf(s, "ncts_atomic_write: %d\n", reg_val); |
| |
| reg_val = get_msr_cts(); |
| seq_printf(s, "CTS: %d\n", reg_val); |
| |
| reg_val = hdmitx_get_bit(HDMITX_DWC_AUD_CTS3, 4); |
| seq_printf(s, "CTS_manual: %d\n", (reg_val & 0x10) >> 4); |
| |
| switch ((reg_val & 0xe0) >> 5) { |
| case 0: |
| conf = "1"; |
| break; |
| case 1: |
| conf = "16"; |
| break; |
| case 2: |
| conf = "32"; |
| break; |
| case 3: |
| conf = "64"; |
| break; |
| case 4: |
| conf = "128"; |
| break; |
| case 5: |
| conf = "256"; |
| break; |
| default: |
| conf = "128"; |
| } |
| seq_printf(s, "N_shift: %s\n", conf); |
| seq_puts(s, "actual N = audN[19:0]/N_shift\n"); |
| } |
| |
| static void hdmitx_parsing_audsamp(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| |
| seq_puts(s, "\n--------parsing AudSample--------\n"); |
| |
| if (hdmitx_get_bit(HDMITX_TOP_CLK_CNTL, 2) || |
| hdmitx_get_bit(HDMITX_TOP_CLK_CNTL, 3)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "AudSample.enable: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_AUD_CONF0; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch ((reg_val & 0x20) >> 5) { |
| case 0: |
| default: |
| conf = "SPDIF"; |
| break; |
| case 1: |
| conf = "I2S"; |
| } |
| seq_printf(s, "i2s_select: %s\n", conf); |
| |
| seq_printf(s, "I2S_in_en: 0x%x\n", reg_val & 0xf); |
| |
| reg_adr = HDMITX_DWC_AUD_CONF1; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "I2S_width: %d bit\n", reg_val & 0x1f); |
| |
| switch ((reg_val & 0xe0) >> 5) { |
| case 0: |
| conf = "standard"; |
| break; |
| case 1: |
| conf = "Right-justified"; |
| break; |
| case 2: |
| conf = "Left-justified"; |
| break; |
| case 3: |
| conf = "Burst 1 mode"; |
| break; |
| case 4: |
| conf = "Burst 2 mode"; |
| break; |
| default: |
| conf = "standard"; |
| } |
| seq_printf(s, "I2S_mode: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_AUD_CONF2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "HBR mode enable: %d\n", reg_val & 0x1); |
| seq_printf(s, "NLPCM mode enable: %d\n", (reg_val & 0x2) >> 1); |
| |
| reg_adr = HDMITX_DWC_AUD_SPDIF1; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "SPDIF_width: %d bit\n", reg_val & 0x1f); |
| seq_printf(s, "SPDIF_HBR_MODE: %d\n", (reg_val & 0x40) >> 6); |
| seq_printf(s, "SPDIF_NLPCM_MODE: %d\n", (reg_val & 0x80) >> 7); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCONF; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "layout: %d\n", reg_val & 0x1); |
| seq_printf(s, "sample flat: %d\n", (reg_val & 0xf0) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSSTAT; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "sample present: %d\n", reg_val & 0xf); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSV; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_puts(s, "audio sample validity flag\n"); |
| seq_printf(s, "channel 0/1/2/3, Left: %d/%d/%d/%d\n", |
| reg_val & 0x1, |
| (reg_val & 0x2) >> 1, |
| (reg_val & 0x4) >> 2, |
| (reg_val & 0x8) >> 3); |
| seq_printf(s, "channel 0/1/2/3, Right: %d/%d/%d/%d\n", |
| (reg_val & 0x10) >> 4, |
| (reg_val & 0x20) >> 5, |
| (reg_val & 0x40) >> 6, |
| (reg_val & 0x80) >> 7); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSU; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_puts(s, "audio sample user flag\n"); |
| seq_printf(s, "channel 0/1/2/3, Left: %d/%d/%d/%d\n", |
| reg_val & 0x1, |
| (reg_val & 0x2) >> 1, |
| (reg_val & 0x4) >> 2, |
| (reg_val & 0x8) >> 3); |
| seq_printf(s, "channel 0/1/2/3, Right: %d/%d/%d/%d\n", |
| (reg_val & 0x10) >> 4, |
| (reg_val & 0x20) >> 5, |
| (reg_val & 0x40) >> 6, |
| (reg_val & 0x80) >> 7); |
| } |
| |
| static void hdmitx_parsing_audchannelst(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| |
| seq_puts(s, "\n--------parsing AudChannelSt--------\n"); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS0; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "iec_copyright: %d\n", reg_val & 0x1); |
| seq_printf(s, "iec_cgmsa: %d\n", (reg_val & 0x30) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS1; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "iec_categorycode: %d\n", reg_val); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "iec_sourcenumber: %d\n", reg_val & 0xf); |
| seq_printf(s, "iec_pcmaudiomode: %d\n", (reg_val & 0x30) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS3; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "iec_channelnumcr0: %d\n", reg_val & 0xf); |
| seq_printf(s, "iec_channelnumcr1: %d\n", (reg_val & 0xf0) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS4; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "iec_channelnumcr2: %d\n", reg_val & 0xf); |
| seq_printf(s, "iec_channelnumcr3: %d\n", (reg_val & 0xf0) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS5; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "iec_channelnumcl0: %d\n", reg_val & 0xf); |
| seq_printf(s, "iec_channelnumcl1: %d\n", (reg_val & 0xf0) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS6; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "iec_channelnumcl2: %d\n", reg_val & 0xf); |
| seq_printf(s, "iec_channelnumcl3: %d\n", (reg_val & 0xf0) >> 4); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS7; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch (reg_val & 0xf) { |
| case 0: |
| conf = "44.1kHz"; |
| break; |
| case 1: |
| conf = "not indicated"; |
| break; |
| case 2: |
| conf = "48kHz"; |
| break; |
| case 3: |
| conf = "32kHz"; |
| break; |
| case 8: |
| conf = "88.2kHz"; |
| break; |
| case 9: |
| conf = "768kHz"; |
| break; |
| case 10: |
| conf = "96kHz"; |
| break; |
| case 12: |
| conf = "176.4kHz"; |
| break; |
| case 14: |
| conf = "192kHz"; |
| break; |
| default: |
| conf = "not indicated"; |
| } |
| seq_printf(s, "iec_sampfreq: %s\n", conf); |
| |
| seq_printf(s, "iec_clk: %d\n", (reg_val & 0x30) >> 4); |
| seq_printf(s, "iec_sampfreq_ext: %d\n", (reg_val & 0xc0) >> 6); |
| |
| reg_adr = HDMITX_DWC_FC_AUDSCHNLS8; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch (reg_val & 0xf) { |
| case 0: |
| case 1: |
| conf = "not indicated"; |
| break; |
| case 2: |
| conf = "16bit"; |
| break; |
| case 4: |
| conf = "18bit"; |
| break; |
| case 8: |
| conf = "19bit"; |
| break; |
| case 10: |
| conf = "20bit"; |
| break; |
| case 12: |
| conf = "17bit"; |
| break; |
| case 3: |
| conf = "20bit"; |
| break; |
| case 5: |
| conf = "22bit"; |
| break; |
| case 9: |
| conf = "23bit"; |
| break; |
| case 11: |
| conf = "24bit"; |
| break; |
| case 13: |
| conf = "21bit"; |
| break; |
| default: |
| conf = "not indicated"; |
| } |
| seq_printf(s, "iec_worldlength: %s\n", conf); |
| |
| switch ((reg_val & 0xf0) >> 4) { |
| case 0: |
| conf = "not indicated"; |
| break; |
| case 1: |
| conf = "192kHz"; |
| break; |
| case 3: |
| conf = "176.4kHz"; |
| break; |
| case 5: |
| conf = "96kHz"; |
| break; |
| case 7: |
| conf = "88.2kHz"; |
| break; |
| case 13: |
| conf = "48kHz"; |
| break; |
| case 15: |
| conf = "44.1kHz"; |
| break; |
| default: |
| conf = "not indicated"; |
| } |
| seq_printf(s, "iec_origsamplefreq: %s\n", conf); |
| } |
| |
| static void hdmitx_parsing_hdrpkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char *conf; |
| unsigned int hcnt, vcnt; |
| struct hdmitx_dev *hdev = get_hdmitx_device(); |
| |
| seq_puts(s, "\n--------parsing DRM/HDR--------\n"); |
| seq_printf(s, "hdr_transfer_feature: 0x%x\n", |
| hdev->hdr_transfer_feature); |
| seq_printf(s, "hdmi_current_hdr_mode: 0x%x\n", |
| hdev->hdmi_current_hdr_mode); |
| seq_printf(s, "hdmi_last_hdr_mode: 0x%x\n", hdev->hdmi_last_hdr_mode); |
| |
| if (hdmitx_get_bit(HDMITX_DWC_FC_DATAUTO3, 6) && |
| hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 7)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "DRM.enable: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_DRM_HB01; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "version: %d\n", reg_val); |
| reg_adr = HDMITX_DWC_FC_DRM_HB02; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| seq_printf(s, "size: %d\n", reg_val); |
| |
| reg_adr = HDMITX_DWC_FC_DRM_PB00; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch (reg_val) { |
| case 0: |
| conf = "sdr"; |
| break; |
| case 1: |
| conf = "hdr"; |
| break; |
| case 2: |
| conf = "ST 2084"; |
| break; |
| case 3: |
| conf = "HLG"; |
| break; |
| default: |
| conf = "sdr"; |
| } |
| seq_printf(s, "eotf: %s\n", conf); |
| |
| reg_adr = HDMITX_DWC_FC_DRM_PB01; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "[0x%x]: 0x%x\n", reg_adr, reg_val); |
| |
| switch (reg_val) { |
| case 0: |
| conf = "static metadata"; |
| break; |
| default: |
| conf = "reserved"; |
| } |
| seq_printf(s, "metadata_id: %s\n", conf); |
| |
| seq_puts(s, "primaries:\n"); |
| for (vcnt = 0; vcnt < 3; vcnt++) { |
| for (hcnt = 0; hcnt < 2; hcnt++) { |
| reg_adr = HDMITX_DWC_FC_DRM_PB02 + |
| (vcnt * 2 + hcnt) * 2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| reg_adr = reg_adr + 1; |
| reg_val = hdmitx_rd_reg(reg_adr) << 8 | reg_val; |
| seq_printf(s, "%u, ", reg_val); |
| } |
| seq_puts(s, "\n"); |
| } |
| |
| seq_puts(s, "white_point: "); |
| for (hcnt = 0; hcnt < 2; hcnt++) { |
| reg_adr = HDMITX_DWC_FC_DRM_PB14 + |
| hcnt * 2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| reg_adr = reg_adr + 1; |
| reg_val = hdmitx_rd_reg(reg_adr) << 8 | reg_val; |
| seq_printf(s, "%u, ", reg_val); |
| } |
| seq_puts(s, "\n"); |
| |
| seq_puts(s, "luminance: "); |
| for (hcnt = 0; hcnt < 2; hcnt++) { |
| reg_adr = HDMITX_DWC_FC_DRM_PB18 + |
| hcnt * 2; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| reg_adr = reg_adr + 1; |
| reg_val = hdmitx_rd_reg(reg_adr) << 8 | reg_val; |
| seq_printf(s, "%u, ", reg_val); |
| } |
| seq_puts(s, "\n"); |
| |
| reg_adr = HDMITX_DWC_FC_DRM_PB22; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| reg_adr = reg_adr + 1; |
| reg_val = hdmitx_rd_reg(reg_adr) << 8 | reg_val; |
| seq_printf(s, "max_content: %u\n", reg_val); |
| reg_adr = HDMITX_DWC_FC_DRM_PB24; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| reg_adr = reg_adr + 1; |
| reg_val = hdmitx_rd_reg(reg_adr) << 8 | reg_val; |
| seq_printf(s, "max_frame_average: %u\n", reg_val); |
| } |
| |
| static void print_current_dv_hdr_(struct seq_file *s) |
| { |
| struct hdmitx_dev *hdev = get_hdmitx_device(); |
| |
| seq_printf(s, "hdmi_current_eotf_type: 0x%x\n", |
| hdev->hdmi_current_eotf_type); |
| seq_printf(s, "hdmi_current_tunnel_mode: 0x%x\n", |
| hdev->hdmi_current_tunnel_mode); |
| seq_printf(s, "dv_src_feature: %d\n", hdev->dv_src_feature); |
| seq_printf(s, "hdr_transfer_feature: %d\n", |
| hdev->hdr_transfer_feature); |
| seq_printf(s, "hdr_color_feature: %d\n", hdev->hdr_color_feature); |
| seq_printf(s, "colormetry: %d\n", hdev->colormetry); |
| } |
| |
| static void hdmitx_parsing_vsifpkt(struct seq_file *s) |
| { |
| unsigned int reg_val; |
| unsigned int reg_adr; |
| unsigned char vsd_ieee_id[3]; |
| unsigned char pb4; |
| unsigned int tmp; |
| unsigned char *conf; |
| unsigned int ieee_code = 0; |
| unsigned int count; |
| |
| seq_puts(s, "\n--------parsing VSIF--------\n"); |
| |
| if (!hdmitx_get_bit(HDMITX_DWC_FC_DATAUTO0, 3) || |
| !hdmitx_get_bit(HDMITX_DWC_FC_PACKET_TX_EN, 4)) |
| conf = "enable"; |
| else |
| conf = "disable"; |
| seq_printf(s, "VSIF.enable: %s\n", conf); |
| |
| DUMP_SECTION(HDMITX_DWC_FC_VSDIEEEID0, HDMITX_DWC_FC_VSDPAYLOAD23); |
| |
| reg_val = hdmitx_rd_reg(HDMITX_DWC_FC_VSDSIZE); |
| seq_printf(s, "size: %d\n", reg_val); |
| |
| /* check VSIF type */ |
| vsd_ieee_id[0] = hdmitx_rd_reg(HDMITX_DWC_FC_VSDIEEEID0); |
| vsd_ieee_id[1] = hdmitx_rd_reg(HDMITX_DWC_FC_VSDIEEEID1); |
| vsd_ieee_id[2] = hdmitx_rd_reg(HDMITX_DWC_FC_VSDIEEEID2); |
| ieee_code = vsd_ieee_id[0] | |
| vsd_ieee_id[1] << 8 | |
| vsd_ieee_id[2] << 16; |
| seq_printf(s, "ieee_id: 0x%x\n", ieee_code); |
| pb4 = hdmitx_rd_reg(HDMITX_DWC_FC_VSDPAYLOAD0); |
| if (ieee_code == HDMI_IEEEOUI && pb4 == 0x20) { |
| /* HDMI 4K */ |
| seq_printf(s, "HDMI 4K %s[%d]\n", __func__, __LINE__); |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD1; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "vic: 0x%x\n", tmp); |
| return; |
| } |
| if (ieee_code == HDMI_IEEEOUI && pb4 == 0x40) { |
| /* HDMI 3D */ |
| seq_printf(s, "HDMI 3D %s[%d]\n", __func__, __LINE__); |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD1; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "3D_structure: 0x%x\n", tmp); |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD2; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "3D_Ext_Data: 0x%x\n", tmp); |
| return; |
| } |
| if (hdmitx_get_cur_dv_st() == HDMI_DV_VSIF_STD) { |
| /* DV STD */ |
| seq_printf(s, "DV STD %s[%d]\n", __func__, __LINE__); |
| print_current_dv_hdr_(s); |
| return; |
| } |
| if (hdmitx_get_cur_dv_st() == HDMI_DV_VSIF_LL) { |
| /* DV LL */ |
| seq_printf(s, "DV LL %s[%d]\n", __func__, __LINE__); |
| print_current_dv_hdr_(s); |
| return; |
| } |
| if (hdmitx_get_cur_hdr10p_st() == HDMI_HDR10P_DV_VSIF) { |
| /* HDR10plus */ |
| seq_printf(s, "HDR10+ %s[%d]\n", __func__, __LINE__); |
| print_current_dv_hdr_(s); |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD0; |
| reg_val = hdmitx_rd_reg(reg_adr); |
| /*hdr 10+ vsif data information*/ |
| seq_printf(s, "app_ver: %u\t", (reg_val >> 6) & 0x3); |
| seq_printf(s, "tar_max_lum: %u\t", (reg_val >> 1) & 0x1f); |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD1; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "avg_maxrgb: %d\t", tmp); |
| |
| for (count = 0; count < 9; count++) { |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD2 + count; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "dist_values: %d\t", tmp); |
| if ((count == 3) || (count == 7) || (count == 8)) |
| seq_puts(s, "\n"); |
| } |
| |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD11; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "nb_curve_anchors: %u\n", (tmp >> 4) & 0xf); |
| reg_val = (tmp & 0xf) << 6; |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD12; |
| tmp = hdmitx_rd_reg(reg_adr); |
| reg_val = reg_val | ((tmp >> 2) & 0x3f); |
| seq_printf(s, "knee_point_x: %u\t", reg_val); |
| |
| reg_val = (tmp & 0x3) << 8; |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD13; |
| tmp = hdmitx_rd_reg(reg_adr); |
| reg_val = reg_val | (tmp & 0xff); |
| seq_printf(s, "knee_point_y: %u\n", reg_val); |
| |
| for (count = 0; count < 9; count++) { |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD14 + count; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "bc_anchors: %d\t", tmp); |
| if ((count == 3) || (count == 7) || (count == 8)) |
| seq_puts(s, "\n"); |
| } |
| |
| reg_adr = HDMITX_DWC_FC_VSDPAYLOAD23; |
| tmp = hdmitx_rd_reg(reg_adr); |
| seq_printf(s, "graph_overlay_flag: %u\t", (tmp >> 7) & 0x1); |
| seq_printf(s, "no_delay_flag: %u\n", (tmp >> 6) & 0x1); |
| return; |
| } |
| } |
| |
| static int dump_hdmipkt_show(struct seq_file *s, void *p) |
| { |
| seq_puts(s, "\n--------HDMITX packets--------\n"); |
| hdmitx_parsing_acrpkt(s); |
| hdmitx_parsing_audsamp(s); |
| hdmitx_parsing_gcppkt(s); |
| hdmitx_parsing_vsifpkt(s); |
| hdmitx_parsing_avipkt(s); |
| hdmitx_parsing_spdpkt(s); |
| hdmitx_parsing_audpkt(s); |
| hdmitx_parsing_audchannelst(s); |
| hdmitx_parsing_hdrpkt(s); |
| |
| return 0; |
| } |
| |
| static int dump_hdmipkt_open(struct inode *inode, struct file *file) |
| { |
| return single_open(file, dump_hdmipkt_show, inode->i_private); |
| } |
| |
| static const struct file_operations dump_hdmipkt_fops = { |
| .open = dump_hdmipkt_open, |
| .read = seq_read, |
| .release = single_release, |
| }; |
| |
| static inline unsigned int get_msr_cts(void) |
| { |
| unsigned int ret = 0; |
| |
| ret = hdmitx_rd_reg(HDMITX_DWC_AUD_CTS1); |
| ret += (hdmitx_rd_reg(HDMITX_DWC_AUD_CTS2) << 8); |
| ret += ((hdmitx_rd_reg(HDMITX_DWC_AUD_CTS3) & 0xf) << 16); |
| |
| return ret; |
| } |
| |
| #define AUD_CTS_LOG_NUM 1000 |
| unsigned int cts_buf[AUD_CTS_LOG_NUM]; |
| static int dump_audcts_show(struct seq_file *s, void *p) |
| { |
| int i; |
| unsigned int min = 0, max = 0, total = 0; |
| |
| seq_puts(s, "\n--------HDMITX audio cts--------\n"); |
| |
| memset(cts_buf, 0, sizeof(cts_buf)); |
| for (i = 0; i < AUD_CTS_LOG_NUM; i++) { |
| cts_buf[i] = get_msr_cts(); |
| mdelay(1); |
| } |
| |
| seq_puts(s, "cts change:\n"); |
| for (i = 1; i < AUD_CTS_LOG_NUM; i++) { |
| if (cts_buf[i] > cts_buf[i - 1]) |
| seq_printf(s, "dis: +%d [%d] %d [%d] %d\n", |
| cts_buf[i] - cts_buf[i - 1], i, |
| cts_buf[i], i - 1, cts_buf[i - 1]); |
| if (cts_buf[i] < cts_buf[i - 1]) |
| seq_printf(s, "dis: %d [%d] %d [%d] %d\n", |
| cts_buf[i] - cts_buf[i - 1], i, |
| cts_buf[i], i - 1, cts_buf[i - 1]); |
| } |
| |
| for (i = 0, min = max = cts_buf[0]; i < AUD_CTS_LOG_NUM; i++) { |
| total += cts_buf[i]; |
| if (min > cts_buf[i]) |
| min = cts_buf[i]; |
| if (max < cts_buf[i]) |
| max = cts_buf[i]; |
| } |
| seq_printf(s, "\nCTS Min: %d Max: %d Avg: %d/1000\n\n", |
| min, max, total); |
| |
| return 0; |
| } |
| |
| static int dump_audcts_open(struct inode *inode, struct file *file) |
| { |
| return single_open(file, dump_audcts_show, inode->i_private); |
| } |
| |
| static const struct file_operations dump_audcts_fops = { |
| .open = dump_audcts_open, |
| .read = seq_read, |
| .release = single_release, |
| }; |
| |
| struct hdmitx_dbg_files_s { |
| const char *name; |
| const umode_t mode; |
| const struct file_operations *fops; |
| }; |
| |
| static struct hdmitx_dbg_files_s hdmitx_dbg_files[] = { |
| {"bus_reg", S_IFREG | 0444, &dump_busreg_fops}, |
| {"hdmi_reg", S_IFREG | 0444, &dump_hdmireg_fops}, |
| {"hdmi_timing", S_IFREG | 0444, &dump_hdmitiming_fops}, |
| {"hdmi_pkt", S_IFREG | 0444, &dump_hdmipkt_fops}, |
| {"aud_cts", S_IFREG | 0444, &dump_audcts_fops}, |
| }; |
| |
| static struct dentry *hdmitx_dbgfs; |
| void hdmitx_debugfs_init(void) |
| { |
| struct dentry *entry; |
| int i; |
| |
| if (hdmitx_dbgfs) |
| return; |
| |
| hdmitx_dbgfs = debugfs_create_dir(DEVICE_NAME, NULL); |
| if (!hdmitx_dbgfs) { |
| pr_err("can't create %s debugfs dir\n", DEVICE_NAME); |
| return; |
| } |
| |
| for (i = 0; i < ARRAY_SIZE(hdmitx_dbg_files); i++) { |
| entry = debugfs_create_file(hdmitx_dbg_files[i].name, |
| hdmitx_dbg_files[i].mode, |
| hdmitx_dbgfs, NULL, |
| hdmitx_dbg_files[i].fops); |
| if (!entry) |
| pr_err("debugfs create file %s failed\n", |
| hdmitx_dbg_files[i].name); |
| } |
| } |
| |
| struct dentry *hdmitx_get_dbgfsdentry(void) |
| { |
| return hdmitx_dbgfs; |
| } |