void hdmirx_set_hpd(int port, unsigned char val) { #ifdef USE_GPIO_FOR_HPD int bitpos = 1; switch(port){ case 0: bitpos=1; break; case 1: bitpos=5; break; case 2: bitpos=9; break; case 3: bitpos=13; break; } if(val){ WRITE_CBUS_REG(PREG_PAD_GPIO5_O, READ_CBUS_REG(PREG_PAD_GPIO5_O) & (~(1<<bitpos))); } else{ WRITE_CBUS_REG(PREG_PAD_GPIO5_O, READ_CBUS_REG(PREG_PAD_GPIO5_O) | (1<<bitpos)); } #else if(val){ hdmirx_wr_top( HDMIRX_TOP_HPD_PWR5V, hdmirx_rd_top(HDMIRX_TOP_HPD_PWR5V)|(1<<rx.port)); } else{ hdmirx_wr_top( HDMIRX_TOP_HPD_PWR5V, hdmirx_rd_top(HDMIRX_TOP_HPD_PWR5V)&(~(1<<rx.port))); } #endif hdmirx_print("%s(%d,%d)\n", __func__, port, val); }
void hdmirx_hw_config(void) { hdmirx_print("%s %d\n", __func__, rx.port); WRITE_CBUS_REG(RESET0_REGISTER, 0x8); //reset HDMIRX module mdelay(10); clk_init(); hdmirx_wr_top(HDMIRX_TOP_INTR_MASKN, 0); //disable top interrupt gate control_reset(0); hdmirx_wr_top( HDMIRX_TOP_PORT_SEL, (1<<rx.port)); //EDID port select hdmirx_interrupts_cfg(false); //disable dwc interrupt if(hdcp_enable){ hdmi_rx_ctrl_hdcp_config(&rx.hdcp); } else { hdmirx_wr_bits_dwc( RA_HDCP_CTRL, HDCP_ENABLE, 0); } /*phy config*/ //hdmirx_phy_restart(); //hdmi_rx_phy_fast_switching(1); phy_init(rx.port, 0); //port, dcm /**/ /* control config */ control_init(rx.port); audio_init(); packet_init(); hdmirx_audio_fifo_rst(); hdmirx_packet_fifo_rst(); /**/ control_reset(1); /*enable irq */ hdmirx_wr_top(HDMIRX_TOP_INTR_STAT_CLR, ~0); hdmirx_wr_top(HDMIRX_TOP_INTR_MASKN, 0x00001fff); hdmirx_interrupts_hpd(true); /**/ #ifndef USE_GPIO_FOR_HPD hdmi_rx_ctrl_hpd(true); hdmirx_wr_top( HDMIRX_TOP_HPD_PWR5V, (1<<5)|(1<<4)); //invert HDP output #endif /* wait at least 4 video frames (at 24Hz) : 167ms for the mode detection recover the video mode */ mdelay(200); /* Check If HDCP engine is in Idle state, if not wait for authentication time. 200ms is enough if no Ri errors */ if (hdmirx_rd_dwc(0xe0) != 0) { mdelay(200); } #if CEC_FUNC_ENABLE cec_init(); #endif }
static void control_reset(unsigned char seq) { unsigned long data32; if(seq==0){ //DWC reset default to be active, until reg HDMIRX_TOP_SW_RESET[0] is set to 0. //hdmirx_rd_check_reg(HDMIRX_DEV_ID_TOP, HDMIRX_TOP_SW_RESET, 0x1, 0x0); // Release IP reset hdmirx_wr_top( HDMIRX_TOP_SW_RESET, 0x0); // Enable functional modules data32 = 0; data32 |= 1 << 5; // [5] cec_enable data32 |= 1 << 4; // [4] aud_enable data32 |= 1 << 3; // [3] bus_enable data32 |= 1 << 2; // [2] hdmi_enable data32 |= 1 << 1; // [1] modet_enable data32 |= 1 << 0; // [0] cfg_enable hdmirx_wr_dwc(RA_DMI_DISABLE_IF, data32); // DEFAULT: {31'd0, 1'b0} mdelay(1); // Reset functional modules hdmirx_wr_dwc(RA_DMI_SW_RST, 0x0000007F); mdelay(1); //hdmirx_rd_check_reg(HDMIRX_DEV_ID_DWC, HDMIRX_DWC_DMI_SW_RST, 0, 0); // RX Reset } else{ data32 = 0; data32 |= 0 << 5; // [5] cec_enable data32 |= 0 << 4; // [4] aud_enable data32 |= 0 << 3; // [3] bus_enable data32 |= 0 << 2; // [2] hdmi_enable data32 |= 0 << 1; // [1] modet_enable data32 |= 1 << 0; // [0] cfg_enable hdmirx_wr_dwc(RA_DMI_DISABLE_IF, data32); // DEFAULT: {31'd0, 1'b0} mdelay(1); //-------------------------------------------------------------------------- // Bring up RX //-------------------------------------------------------------------------- data32 = 0; data32 |= 1 << 5; // [5] cec_enable data32 |= 1 << 4; // [4] aud_enable data32 |= 1 << 3; // [3] bus_enable data32 |= 1 << 2; // [2] hdmi_enable data32 |= 1 << 1; // [1] modet_enable data32 |= 1 << 0; // [0] cfg_enable hdmirx_wr_dwc(RA_DMI_DISABLE_IF, data32); // DEFAULT: {31'd0, 1'b0} mdelay(1); } }
void hdmirx_config_video(struct hdmi_rx_ctrl_video *video_params) { int data32=0; data32 |= 0 << 23; //video_params.pixel_repetition << 23; // [23] hscale_half: 1=Horizontally scale down by half data32 |= 0 << 22; // [22] force_vid_rate: 1=Force video output sample rate data32 |= 0 << 19; // [21:19] force_vid_rate_chroma_cfg : 0=Bypass, not rate change. Applicable only if force_vid_rate=1 data32 |= 0 << 16; // [18:16] force_vid_rate_luma_cfg : 0=Bypass, not rate change. Applicable only if force_vid_rate=1 data32 |= 0x7fff << 0; // [14: 0] hsizem1 hdmirx_wr_top( HDMIRX_TOP_VID_CNTL, data32); }
void clk_init(void) { unsigned int data32; /* DWC clock enable */ Wr_reg_bits(HHI_GCLK_MPEG0, 1, 21, 1); // Turn on clk_hdmirx_pclk, also = sysclk // Enable APB3 fail on error *((volatile unsigned long *) P_HDMIRX_CTRL_PORT) |= (1 << 15); // APB3 to HDMIRX-TOP err_en *((volatile unsigned long *) (P_HDMIRX_CTRL_PORT+0x10)) |= (1 << 15); // APB3 to HDMIRX-DWC err_en //turn on clocks: md, cfg... data32 = 0; data32 |= 0 << 25; // [26:25] HDMIRX mode detection clock mux select: osc_clk data32 |= 1 << 24; // [24] HDMIRX mode detection clock enable data32 |= 0 << 16; // [22:16] HDMIRX mode detection clock divider data32 |= 3 << 9; // [10: 9] HDMIRX config clock mux select: fclk_div5=400MHz data32 |= 1 << 8; // [ 8] HDMIRX config clock enable data32 |= 3 << 0; // [ 6: 0] HDMIRX config clock divider: 400/4=100MHz WRITE_MPEG_REG(HHI_HDMIRX_CLK_CNTL, data32); data32 = 0; data32 |= 2 << 25; // [26:25] HDMIRX ACR ref clock mux select: fclk_div5 data32 |= rx.ctrl.acr_mode << 24; // [24] HDMIRX ACR ref clock enable data32 |= 0 << 16; // [22:16] HDMIRX ACR ref clock divider data32 |= 2 << 9; // [10: 9] HDMIRX audmeas clock mux select: fclk_div5 data32 |= 1 << 8; // [ 8] HDMIRX audmeas clock enable data32 |= 1 << 0; // [ 6: 0] HDMIRX audmeas clock divider: 400/2 = 200MHz WRITE_MPEG_REG(HHI_HDMIRX_AUD_CLK_CNTL, data32); data32 = 0; data32 |= 1 << 17; // [17] audfifo_rd_en data32 |= 1 << 16; // [16] pktfifo_rd_en data32 |= 1 << 2; // [2] hdmirx_cecclk_en data32 |= 0 << 1; // [1] bus_clk_inv data32 |= 0 << 0; // [0] hdmi_clk_inv hdmirx_wr_top( HDMIRX_TOP_CLK_CNTL, data32); // DEFAULT: {32'h0} }
int hdmirx_config_audio(void) { #define AUD_CLK_DELTA 2000 #define RX_8_CHANNEL 1 // 0=I2S 2-channel; 1=I2S 4 x 2-channel. int err = 0; unsigned long data32 = 0; #if 1 data32 = 0; data32 |= 0 << 9; // [9] force_afif_status:1=Use cntl_audfifo_status_cfg as fifo status; 0=Use detected afif_status. data32 |= 1 << 8; // [8] afif_status_auto:1=Enable audio FIFO status auto-exit EMPTY/FULL, if FIFO level is back to LipSync; 0=Once enters EMPTY/FULL, never exits. data32 |= 1 << 6; // [ 7: 6] Audio FIFO nominal level :0=s_total/4;1=s_total/8;2=s_total/16;3=s_total/32. data32 |= 3 << 4; // [ 5: 4] Audio FIFO critical level:0=s_total/4;1=s_total/8;2=s_total/16;3=s_total/32. data32 |= 0 << 3; // [3] afif_status_clr:1=Clear audio FIFO status to IDLE. data32 |= rx.ctrl.acr_mode << 2; // [2] dig_acr_en data32 |= 0 << 1; // [1] audmeas_clk_sel: 0=select aud_pll_clk; 1=select aud_acr_clk. data32 |= rx.ctrl.acr_mode << 0; // [0] aud_clk_sel: 0=select aud_pll_clk; 1=select aud_acr_clk. hdmirx_wr_top( HDMIRX_TOP_ACR_CNTL_STAT, data32); //hdmirx_wr_dwc( RA_AUDPLL_GEN_CTS, manual_acr_cts); //hdmirx_wr_dwc( RA_AUDPLL_GEN_N, manual_acr_n); #if 0 // Force N&CTS to start with, will switch to received values later on, for simulation speed up. data32 = 0; data32 |= 1 << 4; // [4] cts_n_ref: 0=used decoded; 1=use manual N&CTS. hdmirx_wr_dwc( RA_AUD_CLK_CTRL, data32); #endif data32 = 0; data32 |= 0 << 28; // [28] pll_lock_filter_byp data32 |= 0 << 24; // [27:24] pll_lock_toggle_div hdmirx_wr_dwc( RA_AUD_PLL_CTRL, data32); // DEFAULT: {1'b0, 3'd0, 4'd6, 4'd3, 4'd8, 1'b0, 1'b0, 1'b1, 1'b0, 12'd0} data32 = 0; data32 |= 80 << 18; // [26:18] afif_th_start data32 |= 8 << 9; // [17:9] afif_th_max data32 |= 8 << 0; // [8:0] afif_th_min hdmirx_wr_dwc( RA_AUD_FIFO_TH, data32); data32 = 0; data32 |= 1 << 16; // [16] afif_subpackets: 0=store all sp; 1=store only the ones' spX=1. data32 |= 0 << 0; // [0] afif_init hdmirx_wr_dwc( RA_AUD_FIFO_CTRL, data32); // DEFAULT: {13'd0, 2'd0, 1'b1, 15'd0, 1'b0} data32 = 0; data32 |= (RX_8_CHANNEL? 0x7 :0x0) << 8; // [10:8] ch_map[7:5] data32 |= 1 << 7; // [7] ch_map_manual data32 |= (RX_8_CHANNEL? 0x1f:0x3) << 2; // [6:2] ch_map[4:0] data32 |= 1 << 0; // [1:0] aud_layout_ctrl:0/1=auto layout; 2=layout 0; 3=layout 1. hdmirx_wr_dwc( RA_AUD_CHEXTRA_CTRL, data32); // DEFAULT: {24'd0, 1'b0, 5'd0, 2'd0} #endif /* amlogic HDMIRX audio module enable*/ WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL, 0x60010000); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL2, 0x814d3928); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL3, 0x6b425012); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL4, 0x101); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL5, 0x8550d20); if(rx.aud_info.audio_recovery_clock > (96000 + AUD_CLK_DELTA)){ if(rx.ctrl.tmds_clk2 <= 36000000) { printk("tmds_clk2 <= 36000000\n"); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL6, 0x55013000); } else if (rx.ctrl.tmds_clk2 <= 53000000) { printk("tmds_clk2 <= 53000000\n"); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL6, 0x55053000); } else { printk("tmds_clk2 > 53000000\n"); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL6, 0x55153000); } } else { printk("audio_recovery_clock > 98000\n"); WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL6, 0x55153000); } WRITE_MPEG_REG(HHI_AUDCLK_PLL_CNTL, 0x00010000); //reset /**/ #if 0 WRITE_MPEG_REG(AUDIN_SOURCE_SEL, (0 <<12) | // [14:12]cntl_hdmirx_chsts_sel: 0=Report chan1 status; 1=Report chan2 status; ...; 7=Report chan8 status. (0xf<<8) | // [11:8] cntl_hdmirx_chsts_en (1 <<4) | // [5:4] spdif_src_sel: 1=Select HDMIRX SPDIF output as AUDIN source (2 << 0)); // [1:0] i2sin_src_sel: 2=Select HDMIRX I2S output as AUDIN source #endif return err; }
static void control_init_more(void) { #define VSYNC_POLARITY 1 // TX VSYNC polarity: 0=low active; 1=high active. unsigned long data32; data32 = 0; data32 |= 0 << 13; // [ 13] checksum_init_mode data32 |= EDID_AUTO_CHECKSUM_ENABLE << 12; // [ 12] auto_checksum_enable data32 |= EDID_AUTO_CEC_ENABLE << 11; // [ 11] auto_cec_enable data32 |= 0 << 10; // [ 10] scl_stretch_trigger_config data32 |= 0 << 9; // [ 9] force_scl_stretch_trigger data32 |= 1 << 8; // [ 8] scl_stretch_enable data32 |= EDID_CLK_DIVIDE_M1 << 0; // [ 7: 0] clk_divide_m1 hdmirx_wr_top(HDMIRX_TOP_EDID_GEN_CNTL, data32); #if 0 data32 = 0; data32 |= VSYNC_POLARITY << 3; // [4:3] vs_pol_adj_mode:0=invert input VS; 1=no invert; 2=auto convert to high active; 3=no invert. data32 |= 2 << 1; // [2:1] hs_pol_adj_mode:0=invert input VS; 1=no invert; 2=auto convert to high active; 3=no invert. hdmirx_wr_dwc( RA_HDMI_SYNC_CTRL, data32); // DEFAULT: {27'd0, 2'd0, 2'd0, 1'b0} #endif #define interlace_mode 1 data32 = 0; data32 |= 1 << 4; // [4] v_offs_lin_mode data32 |= 1 << 1; // [1] v_edge data32 |= interlace_mode << 0; // [0] v_mode hdmirx_wr_dwc( RA_MD_VCTRL, data32); // DEFAULT: {27'd0, 1'b0, 2'd0, 1'b1, 1'b0} data32 = 0; data32 |= 0 << 20; // [20] rg_block_off:1=Enable HS/VS/CTRL filtering during active video data32 |= 1 << 19; // [19] block_off:1=Enable HS/VS/CTRL passing during active video data32 |= 5 << 16; // [18:16] valid_mode data32 |= 0 << 12; // [13:12] ctrl_filt_sens data32 |= 3 << 10; // [11:10] vs_filt_sens data32 |= 0 << 8; // [9:8] hs_filt_sens data32 |= 2 << 6; // [7:6] de_measure_mode data32 |= 0 << 5; // [5] de_regen data32 |= 3 << 3; // [4:3] de_filter_sens hdmirx_wr_dwc( RA_HDMI_ERRORA_PROTECT, data32); // DEFAULT: {11'd0, 1'b0, 1'b0, 3'd0, 2'd0, 2'd0, 2'd0, 2'd0, 2'd0, 1'b0, 2'd0, 3'd0} data32 = 0; data32 |= 0 << 8; // [10:8] hact_pix_ith data32 |= 0 << 5; // [5] hact_pix_src data32 |= 1 << 4; // [4] htot_pix_src hdmirx_wr_dwc( RA_MD_HCTRL1, data32); // DEFAULT: {21'd0, 3'd1, 2'd0, 1'b0, 1'b1, 4'd0} data32 = 0; data32 |= 1 << 12; // [14:12] hs_clk_ith data32 |= 7 << 8; // [10:8] htot32_clk_ith data32 |= 1 << 5; // [5] vs_act_time data32 |= 3 << 3; // [4:3] hs_act_time data32 |= 0 << 0; // [1:0] h_start_pos hdmirx_wr_dwc( RA_MD_HCTRL2, data32); // DEFAULT: {17'd0, 3'd2, 1'b0, 3'd1, 2'd0, 1'b0, 2'd0, 1'b0, 2'd2} data32 = 0; data32 |= 1 << 10; // [11:10] vofs_lin_ith data32 |= 3 << 8; // [9:8] vact_lin_ith data32 |= 0 << 6; // [7:6] vtot_lin_ith data32 |= 7 << 3; // [5:3] vs_clk_ith data32 |= 2 << 0; // [2:0] vtot_clk_ith hdmirx_wr_dwc( RA_MD_VTH, data32); // DEFAULT: {20'd0, 2'd2, 2'd0, 2'd0, 3'd2, 3'd2} data32 = 0; data32 |= 1 << 2; // [2] fafielddet_en data32 |= 0 << 0; // [1:0] field_pol_mode hdmirx_wr_dwc( RA_MD_IL_POL, data32); // DEFAULT: {29'd0, 1'b0, 2'd0} data32 = 0; data32 |= 0 << 1; // [4:1] man_vid_derepeat data32 |= 1 << 0; // [0] auto_derepeat hdmirx_wr_dwc( RA_HDMI_RESMPL_CTRL, data32); // DEFAULT: {27'd0, 4'd0, 1'b1} }