| /* |
| * drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h |
| * |
| * 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. |
| * |
| */ |
| |
| #ifndef _TVHDMI_H |
| #define _TVHDMI_H |
| |
| #include <linux/workqueue.h> |
| #include <linux/extcon.h> |
| |
| |
| #include <linux/amlogic/cpu_version.h> |
| #include <linux/amlogic/media/frame_provider/tvin/tvin.h> |
| #include <linux/amlogic/iomap.h> |
| #include <linux/cdev.h> |
| #include <linux/irqreturn.h> |
| #include "../tvin_global.h" |
| #include "../tvin_frontend.h" |
| //#include "hdmirx_repeater.h" |
| //#include "hdmi_rx_pktinfo.h" |
| #include "hdmi_rx_edid.h" |
| |
| |
| #define RX_VER0 "ver.2019-03-25" |
| /* |
| * |
| * |
| * |
| * |
| */ |
| #define RX_VER1 "ver.2019/03/15" |
| /* |
| * |
| * |
| */ |
| #define RX_VER2 "ver.2019/03/19" |
| |
| /*print type*/ |
| #define LOG_EN 0x01 |
| #define VIDEO_LOG 0x02 |
| #define AUDIO_LOG 0x04 |
| #define HDCP_LOG 0x08 |
| #define PACKET_LOG 0x10 |
| #define EQ_LOG 0x20 |
| #define REG_LOG 0x40 |
| #define ERR_LOG 0x80 |
| #define EDID_LOG 0x100 |
| #define VSI_LOG 0x800 |
| |
| /* 50ms timer for hdmirx main loop (HDMI_STATE_CHECK_FREQ is 20) */ |
| |
| |
| #define ABS(x) ((x) < 0 ? -(x) : (x)) |
| |
| #define EDID_MIX_MAX_SIZE 64 |
| |
| #define ESM_KILL_WAIT_TIMES 250 |
| #define str_cmp(buff, str) ((strlen((str)) == strlen((buff))) && \ |
| (strncmp((buff), (str), strlen((str))) == 0)) |
| #define pr_var(str, index) rx_pr("%5d %-30s = %#x\n", (index), #str, (str)) |
| #define var_to_str(var) (#var) |
| #define var_str_cmp(str, var) str_cmp((str), (#var)) |
| #define set_pr_var(a, b, c, d, e) (comp_set_pr_var((a), \ |
| (var_to_str(b)), (&b), (c), (d), (e), (sizeof(b)))) |
| |
| |
| |
| |
| #define PFIFO_SIZE 160 |
| |
| enum chip_id_e { |
| CHIP_ID_GXTVBB, |
| CHIP_ID_TXL, |
| CHIP_ID_TXLX, |
| CHIP_ID_TXHD, |
| CHIP_ID_TL1, |
| }; |
| |
| enum phy_ver_e { |
| PHY_VER_ORG, |
| PHY_VER_TL1, |
| }; |
| |
| struct meson_hdmirx_data { |
| enum chip_id_e chip_id; |
| enum phy_ver_e phy_ver; |
| struct ctrl *phyctrl; |
| }; |
| |
| struct hdmirx_dev_s { |
| int index; |
| dev_t devt; |
| struct cdev cdev; |
| struct device *dev; |
| struct tvin_parm_s param; |
| struct timer_list timer; |
| struct tvin_frontend_s frontend; |
| unsigned int irq; |
| char irq_name[12]; |
| struct mutex rx_lock; |
| /*struct mutex pd_fifo_lock;*/ |
| struct clk *modet_clk; |
| struct clk *cfg_clk; |
| struct clk *acr_ref_clk; |
| struct clk *audmeas_clk; |
| struct clk *aud_out_clk; |
| struct clk *esm_clk; |
| struct clk *skp_clk; |
| struct clk *meter_clk; |
| struct clk *axi_clk; |
| const struct meson_hdmirx_data *data; |
| }; |
| |
| #define HDMI_IOC_MAGIC 'H' |
| #define HDMI_IOC_HDCP_ON _IO(HDMI_IOC_MAGIC, 0x01) |
| #define HDMI_IOC_HDCP_OFF _IO(HDMI_IOC_MAGIC, 0x02) |
| #define HDMI_IOC_EDID_UPDATE _IO(HDMI_IOC_MAGIC, 0x03) |
| #define HDMI_IOC_PC_MODE_ON _IO(HDMI_IOC_MAGIC, 0x04) |
| #define HDMI_IOC_PC_MODE_OFF _IO(HDMI_IOC_MAGIC, 0x05) |
| #define HDMI_IOC_HDCP22_AUTO _IO(HDMI_IOC_MAGIC, 0x06) |
| #define HDMI_IOC_HDCP22_FORCE14 _IO(HDMI_IOC_MAGIC, 0x07) |
| #define HDMI_IOC_HDMI_20_SET _IO(HDMI_IOC_MAGIC, 0x08) |
| #define HDMI_IOC_HDCP_GET_KSV _IOR(HDMI_IOC_MAGIC, 0x09, struct _hdcp_ksv) |
| #define HDMI_IOC_PD_FIFO_PKTTYPE_EN _IOW(HDMI_IOC_MAGIC, 0x0a,\ |
| uint32_t) |
| #define HDMI_IOC_PD_FIFO_PKTTYPE_DIS _IOW(HDMI_IOC_MAGIC, 0x0b,\ |
| uint32_t) |
| #define HDMI_IOC_GET_PD_FIFO_PARAM _IOWR(HDMI_IOC_MAGIC, 0x0c,\ |
| struct pd_infoframe_s) |
| #define HDMI_IOC_HDCP14_KEY_MODE _IOR(HDMI_IOC_MAGIC, 0x0d,\ |
| enum hdcp14_key_mode_e) |
| #define HDMI_IOC_HDCP22_NOT_SUPPORT _IO(HDMI_IOC_MAGIC, 0x0e) |
| |
| #define IOC_SPD_INFO _BIT(0) |
| #define IOC_AUD_INFO _BIT(1) |
| #define IOC_MPEGS_INFO _BIT(2) |
| #define IOC_AVI_INFO _BIT(3) |
| #define ALL_PORTS ((1 << E_PORT_NUM) - 1) |
| |
| enum colorspace_e { |
| E_COLOR_RGB, |
| E_COLOR_YUV422, |
| E_COLOR_YUV444, |
| E_COLOR_YUV420, |
| }; |
| |
| enum colorrange_e { |
| E_RANGE_DEFAULT, |
| E_RANGE_LIMIT, |
| E_RANGE_FULL, |
| }; |
| |
| enum colordepth_e { |
| E_COLORDEPTH_8 = 8, |
| E_COLORDEPTH_10 = 10, |
| E_COLORDEPTH_12 = 12, |
| E_COLORDEPTH_16 = 16, |
| }; |
| |
| enum port_sts_e { |
| E_PORT0, |
| E_PORT1, |
| E_PORT2, |
| E_PORT3, |
| E_PORT_NUM, |
| E_5V_LOST = 0xfd, |
| E_INIT = 0xff, |
| }; |
| |
| enum hdcp_version_e { |
| HDCP_VER_NONE, |
| HDCP_VER_14, |
| HDCP_VER_22, |
| }; |
| |
| enum hdmirx_port_e { |
| HDMIRX_PORT0, |
| HDMIRX_PORT1, |
| HDMIRX_PORT2, |
| HDMIRX_PORT3, |
| }; |
| |
| enum map_addr_module_e { |
| MAP_ADDR_MODULE_CBUS, |
| MAP_ADDR_MODULE_HIU, |
| MAP_ADDR_MODULE_HDMIRX_CAPB3, |
| MAP_ADDR_MODULE_SEC_AHB, |
| MAP_ADDR_MODULE_SEC_AHB2, |
| MAP_ADDR_MODULE_APB4, |
| MAP_ADDR_MODULE_TOP, |
| MAP_ADDR_MODULE_NUM |
| }; |
| |
| enum rx_cn_type_e { |
| CN_GRAPHICS, |
| CN_PHOTO, |
| CN_CINEMA, |
| CN_GAME, |
| }; |
| |
| /** |
| * @short HDMI RX controller video parameters |
| * |
| * For Auxiliary Video InfoFrame (AVI) details see HDMI 1.4a section 8.2.2 |
| */ |
| struct rx_video_info { |
| /** DVI detection status: DVI (true) or HDMI (false) */ |
| bool hw_dvi; |
| |
| uint8_t hdcp_type; |
| /** bit'0:auth start bit'1:enc state(0:not endrypted 1:encrypted) **/ |
| uint8_t hdcp14_state; |
| /** 1:decrypted 0:encrypted **/ |
| uint8_t hdcp22_state; |
| /** Deep color mode: 8, 10, 12 or 16 [bits per pixel] */ |
| uint8_t colordepth; |
| /** Pixel clock frequency [kHz] */ |
| uint32_t pixel_clk; |
| /** Refresh rate [0.01Hz] */ |
| uint32_t frame_rate; |
| /** Interlaced */ |
| bool interlaced; |
| /** Vertical offset */ |
| uint32_t voffset; |
| /** Vertical active */ |
| uint32_t vactive; |
| /** Vertical total */ |
| uint32_t vtotal; |
| /** Horizontal offset */ |
| uint32_t hoffset; |
| /** Horizontal active */ |
| uint32_t hactive; |
| /** Horizontal total */ |
| uint32_t htotal; |
| /** AVI Y1-0, video format */ |
| uint8_t colorspace; |
| /** AVI VIC6-0, video identification code */ |
| enum hdmi_vic_e hw_vic; |
| /** AVI PR3-0, pixel repetition factor */ |
| uint8_t repeat; |
| /* for sw info */ |
| enum hdmi_vic_e sw_vic; |
| uint8_t sw_dvi; |
| unsigned int it_content; |
| enum rx_cn_type_e cn_type; |
| /** AVI Q1-0, RGB quantization range */ |
| unsigned int rgb_quant_range; |
| /** AVI Q1-0, YUV quantization range */ |
| unsigned int yuv_quant_range; |
| bool sw_fp; |
| bool sw_alternative; |
| }; |
| |
| /** Receiver key selection size - 40 bits */ |
| #define HDCP_BKSV_SIZE (2 * 1) |
| /** Encrypted keys size - 40 bits x 40 keys */ |
| #define HDCP_KEYS_SIZE (2 * 40) |
| |
| /*emp buffer config*/ |
| #define DUMP_MODE_EMP 0 |
| #define DUMP_MODE_TMDS 1 |
| #define TMDS_BUFFER_SIZE 0x2000000 /*32M*/ |
| #define EMP_BUFFER_SIZE 0x200000 /*2M*/ |
| #define EMP_BUFF_MAX_PKT_CNT ((EMP_BUFFER_SIZE/2)/32 - 200) |
| #define TMDS_DATA_BUFFER_SIZE 0x200000 |
| |
| |
| /** |
| * @short HDMI RX controller HDCP configuration |
| */ |
| struct hdmi_rx_hdcp { |
| /*hdcp auth state*/ |
| enum repeater_state_e state; |
| /** Repeater mode else receiver only */ |
| bool repeat; |
| bool cascade_exceed; |
| bool dev_exceed; |
| /*downstream depth*/ |
| unsigned char depth; |
| /*downstream count*/ |
| uint32_t count; |
| /** Key description seed */ |
| uint32_t seed; |
| uint32_t delay;/*according to the timer,5s*/ |
| /** |
| * Receiver key selection |
| * @note 0: high order, 1: low order |
| */ |
| uint32_t bksv[HDCP_BKSV_SIZE]; |
| /** |
| * Encrypted keys |
| * @note 0: high order, 1: low order |
| */ |
| uint32_t keys[HDCP_KEYS_SIZE]; |
| struct extcon_dev *rx_excton_auth; |
| enum hdcp_version_e hdcp_version;/* 0 no hdcp;1 hdcp14;2 hdcp22 */ |
| unsigned char hdcp22_exception;/*esm exception code,reg addr :0x60*/ |
| }; |
| |
| static const unsigned int rx22_ext[] = { |
| EXTCON_DISP_HDMI, |
| EXTCON_NONE, |
| }; |
| struct vsi_info_s { |
| unsigned int identifier; |
| unsigned char vd_fmt; |
| unsigned char _3d_structure; |
| unsigned char _3d_ext_data; |
| bool dolby_vision; |
| bool low_latency; |
| bool backlt_md_bit; |
| unsigned int dolby_timeout; |
| unsigned int eff_tmax_pq; |
| bool allm_mode; |
| }; |
| |
| #define CHANNEL_STATUS_SIZE 24 |
| |
| struct aud_info_s { |
| /* info frame*/ |
| /* |
| *unsigned char cc; |
| *unsigned char ct; |
| *unsigned char ss; |
| *unsigned char sf; |
| */ |
| |
| int coding_type; |
| int channel_count; |
| int sample_frequency; |
| int sample_size; |
| int coding_extension; |
| int auds_ch_alloc; |
| int auds_layout; |
| |
| /* |
| *int down_mix_inhibit; |
| *int level_shift_value; |
| */ |
| int aud_hbr_rcv; |
| int aud_packet_received; |
| |
| /* channel status */ |
| unsigned char channel_status[CHANNEL_STATUS_SIZE]; |
| unsigned char channel_status_bak[CHANNEL_STATUS_SIZE]; |
| /**/ |
| unsigned int cts; |
| unsigned int n; |
| unsigned int arc; |
| /**/ |
| int real_channel_num; |
| int real_sample_size; |
| int real_sr; |
| }; |
| |
| struct phy_sts { |
| uint32_t cable_clk; |
| uint32_t tmds_clk; |
| uint32_t aud_div; |
| uint32_t pll_rate; |
| uint32_t clk_rate; |
| uint32_t phy_bw; |
| uint32_t pll_bw; |
| uint32_t cablesel; |
| ulong timestap; |
| uint32_t err_sum; |
| uint32_t eq_data[256]; |
| }; |
| |
| struct emp_buff { |
| unsigned int dump_mode; |
| struct page *pg_addr; |
| phys_addr_t p_addr_a; |
| phys_addr_t p_addr_b; |
| /*void __iomem *v_addr_a;*/ |
| /*void __iomem *v_addr_b;*/ |
| void __iomem *storeA; |
| void __iomem *storeB; |
| void __iomem *ready; |
| unsigned long irqcnt; |
| unsigned int emppktcnt; |
| unsigned int tmdspktcnt; |
| }; |
| |
| struct rx_s { |
| enum chip_id_e chip_id; |
| struct hdmirx_dev_s *hdmirxdev; |
| /** HDMI RX received signal changed */ |
| uint8_t skip; |
| /*avmute*/ |
| uint32_t avmute_skip; |
| /** HDMI RX input port 0 (A) or 1 (B) (or 2(C) or 3 (D)) */ |
| uint8_t port; |
| /* first boot flag */ |
| /* workaround for xiaomi-MTK box: */ |
| /* if box is under suspend and it worked at hdcp2.2 mode before, */ |
| /* must do hpd reset and keep hpd low at least 2S to ensure hdcp2.2 */ |
| /* work normally, otherwise mibox's hdcp22 module will pull down SDA */ |
| /* and stop EDID communication.*/ |
| /* compare with LG & LETV, the result is the same. */ |
| bool boot_flag; |
| bool open_fg; |
| uint8_t irq_flag; |
| bool firm_change;/*hdcp2.2 rp/rx switch time*/ |
| /** HDMI RX controller HDCP configuration */ |
| struct hdmi_rx_hdcp hdcp; |
| /*report hpd status to app*/ |
| struct extcon_dev *rx_excton_rx22; |
| struct extcon_dev *rx_excton_open; |
| |
| /* wrapper */ |
| unsigned int state; |
| unsigned int pre_state; |
| /* recovery mode */ |
| unsigned char err_rec_mode; |
| unsigned char err_code; |
| unsigned char pre_5v_sts; |
| unsigned char cur_5v_sts; |
| bool no_signal; |
| unsigned char err_cnt; |
| uint16_t wait_no_sig_cnt; |
| int aud_sr_stable_cnt; |
| int aud_sr_unstable_cnt; |
| unsigned long int timestamp; |
| unsigned long int stable_timestamp; |
| unsigned long int unready_timestamp; |
| /* info */ |
| struct rx_video_info pre; |
| struct rx_video_info cur; |
| struct aud_info_s aud_info; |
| struct vsi_info_s vs_info_details; |
| struct tvin_hdr_info_s hdr_info; |
| unsigned char edid_mix_buf[EDID_MIX_MAX_SIZE]; |
| unsigned int pwr_sts; |
| /* for debug */ |
| /*struct pd_infoframe_s dbg_info;*/ |
| struct phy_sts phy; |
| struct emp_buff empbuff; |
| }; |
| |
| struct _hdcp_ksv { |
| uint32_t bksv0; |
| uint32_t bksv1; |
| }; |
| |
| struct reg_map { |
| unsigned int phy_addr; |
| unsigned int size; |
| void __iomem *p; |
| int flag; |
| }; |
| |
| /* system */ |
| extern struct delayed_work eq_dwork; |
| extern struct workqueue_struct *eq_wq; |
| extern struct delayed_work esm_dwork; |
| extern struct workqueue_struct *esm_wq; |
| extern struct delayed_work repeater_dwork; |
| extern struct workqueue_struct *repeater_wq; |
| extern struct tasklet_struct rx_tasklet; |
| extern struct device *hdmirx_dev; |
| extern struct rx_s rx; |
| extern struct reg_map reg_maps[MAP_ADDR_MODULE_NUM]; |
| extern bool downstream_repeat_support; |
| extern void rx_tasklet_handler(unsigned long arg); |
| extern void skip_frame(unsigned int cnt); |
| extern int cec_set_dev_info(uint8_t dev_idx); |
| |
| /* reg */ |
| |
| |
| /* hotplug */ |
| extern unsigned int pwr_sts; |
| extern int pre_port; |
| extern void hotplug_wait_query(void); |
| extern void rx_send_hpd_pulse(void); |
| |
| /* irq */ |
| extern void rx_irq_en(bool enable); |
| extern irqreturn_t irq_handler(int irq, void *params); |
| extern void cecb_irq_handle(void); |
| |
| /* user interface */ |
| extern int pc_mode_en; |
| extern int it_content; |
| extern int rgb_quant_range; |
| extern int yuv_quant_range; |
| extern int en_4k_timing; |
| extern bool en_4096_2_3840; |
| extern int en_4k_2_2k; |
| extern bool hdmi_cec_en; |
| extern int hdmi_yuv444_enable; |
| extern int vdin_drop_frame_cnt; |
| /* debug */ |
| extern bool hdcp_enable; |
| extern int log_level; |
| extern int sm_pause; |
| extern int suspend_pddq_sel; |
| extern int disable_port_num; |
| extern int disable_port_en; |
| extern int rx_set_global_variable(const char *buf, int size); |
| extern void rx_get_global_variable(const char *buf); |
| extern int rx_pr(const char *fmt, ...); |
| extern unsigned int hdmirx_hw_dump_reg(unsigned char *buf, int size); |
| extern unsigned int hdmirx_show_info(unsigned char *buf, int size); |
| extern bool is_afifo_error(void); |
| extern bool is_aud_pll_error(void); |
| extern int hdmirx_debug(const char *buf, int size); |
| extern void dump_reg(void); |
| extern void dump_edid_reg(void); |
| extern void rx_debug_loadkey(void); |
| extern void rx_debug_load22key(void); |
| extern int rx_debug_wr_reg(const char *buf, char *tmpbuf, int i); |
| extern int rx_debug_rd_reg(const char *buf, char *tmpbuf); |
| |
| /* repeater */ |
| bool hdmirx_repeat_support(void); |
| |
| /* edid-hdcp14 */ |
| extern unsigned int edid_update_flag; |
| extern unsigned int downstream_hpd_flag; |
| |
| extern void hdmirx_fill_edid_buf(const char *buf, int size); |
| extern unsigned int hdmirx_read_edid_buf(char *buf, int max_size); |
| extern void hdmirx_fill_key_buf(const char *buf, int size); |
| |
| /* packets */ |
| extern int dv_nopacket_timeout; |
| extern unsigned int packet_fifo_cfg; |
| extern unsigned int *pd_fifo_buf; |
| |
| |
| |
| /* for other modules */ |
| extern int External_Mute(int mute_flag); |
| extern void vdac_enable(bool on, unsigned int module_sel); |
| extern int rx_is_hdcp22_support(void); |
| extern int hdmirx_get_connect_info(void); |
| #endif |