static void rk30_hdmi_config_phy(unsigned char vic) { HDMIWrReg(DEEP_COLOR_MODE, 0x22); // tmds frequency same as input dlck rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); switch(vic) { case HDMI_1920x1080p_60Hz: case HDMI_1920x1080p_50Hz: rk30_hdmi_config_phy_reg(0x158, 0x0E); rk30_hdmi_config_phy_reg(0x15c, 0x00); rk30_hdmi_config_phy_reg(0x160, 0x60); rk30_hdmi_config_phy_reg(0x164, 0x00); rk30_hdmi_config_phy_reg(0x168, 0xDA); rk30_hdmi_config_phy_reg(0x16c, 0xA1); rk30_hdmi_config_phy_reg(0x170, 0x0e); rk30_hdmi_config_phy_reg(0x174, 0x22); rk30_hdmi_config_phy_reg(0x178, 0x00); break; case HDMI_1920x1080i_60Hz: case HDMI_1920x1080i_50Hz: case HDMI_1280x720p_60Hz: case HDMI_1280x720p_50Hz: rk30_hdmi_config_phy_reg(0x158, 0x06); rk30_hdmi_config_phy_reg(0x15c, 0x00); rk30_hdmi_config_phy_reg(0x160, 0x60); rk30_hdmi_config_phy_reg(0x164, 0x00); rk30_hdmi_config_phy_reg(0x168, 0xCA); rk30_hdmi_config_phy_reg(0x16c, 0xA3); rk30_hdmi_config_phy_reg(0x170, 0x0e); rk30_hdmi_config_phy_reg(0x174, 0x20); rk30_hdmi_config_phy_reg(0x178, 0x00); break; case HDMI_720x576p_50Hz_4_3: case HDMI_720x576p_50Hz_16_9: case HDMI_720x480p_60Hz_4_3: case HDMI_720x480p_60Hz_16_9: rk30_hdmi_config_phy_reg(0x158, 0x02); rk30_hdmi_config_phy_reg(0x15c, 0x00); rk30_hdmi_config_phy_reg(0x160, 0x60); rk30_hdmi_config_phy_reg(0x164, 0x00); rk30_hdmi_config_phy_reg(0x168, 0xC2); rk30_hdmi_config_phy_reg(0x16c, 0xA2); rk30_hdmi_config_phy_reg(0x170, 0x0e); rk30_hdmi_config_phy_reg(0x174, 0x20); rk30_hdmi_config_phy_reg(0x178, 0x00); break; default: hdmi_err(hdmi->dev, "not support such vic %d\n", vic); break; } }
int rk3288_hdmi_video_sampler(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara) { int map_code = 0; struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); if (vpara->input_color == VIDEO_INPUT_COLOR_RGB || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444 || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR420) { switch (vpara->color_depth) { case HDMI_COLOR_DEPTH_8BIT: map_code = VIDEO_RGB444_8BIT; break; case HDMI_COLOR_DEPTH_10BIT: map_code = VIDEO_RGB444_10BIT; break; case HDMI_COLOR_DEPTH_12BIT: map_code = VIDEO_RGB444_12BIT; break; case HDMI_COLOR_DEPTH_16BIT: map_code = VIDEO_RGB444_16BIT; break; default: map_code = VIDEO_RGB444_8BIT; break; } map_code += (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) ? 8 : 0; } else if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422) { /* YCC422 mapping is discontinued - only map 1 is supported */ switch (vpara->color_depth) { case HDMI_COLOR_DEPTH_8BIT: map_code = VIDEO_YCBCR422_8BIT; break; case HDMI_COLOR_DEPTH_10BIT: map_code = VIDEO_YCBCR422_10BIT; break; case HDMI_COLOR_DEPTH_12BIT: map_code = VIDEO_YCBCR422_12BIT; break; default: map_code = VIDEO_YCBCR422_8BIT; break; } } else { hdmi_err(hdmi_drv->dev, "invalid input color type: %d", vpara->input_color); return -1; } //Set Data enable signal from external and set video sample input mapping hdmi_msk_reg(hdmi_dev, TX_INVID0, m_INTERNAL_DE_GEN | m_VIDEO_MAPPING, v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code)); #if defined(HDMI_VIDEO_STUFFING) hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00); hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00); hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_GYDATA_STUFF, v_GYDATA_STUFF(1)); hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00); hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00); hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_RCRDATA_STUFF, v_RCRDATA_STUFF(1)); hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00); hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00); hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_BCBDATA_STUFF, v_BCBDATA_STUFF(1)); #endif return 0; }
static int rk3288_hdmi_video_packetizer(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara) { unsigned char color_depth = 0; unsigned char output_select = 0; unsigned char remap_size = 0; struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); if (vpara->output_color == VIDEO_OUTPUT_RGB444 || vpara->output_color == VIDEO_OUTPUT_YCBCR444 || vpara->output_color == VIDEO_OUTPUT_YCBCR420) { switch (vpara->color_depth) { case HDMI_COLOR_DEPTH_8BIT: color_depth = COLOR_DEPTH_24BIT; output_select = OUT_FROM_8BIT_BYPASS; break; case HDMI_COLOR_DEPTH_10BIT: color_depth = COLOR_DEPTH_30BIT; output_select = OUT_FROM_PIXEL_PACKING; break; case HDMI_COLOR_DEPTH_12BIT: color_depth = COLOR_DEPTH_36BIT; output_select = OUT_FROM_PIXEL_PACKING; break; case HDMI_COLOR_DEPTH_16BIT: color_depth = COLOR_DEPTH_48BIT; output_select = OUT_FROM_PIXEL_PACKING; break; default: color_depth = COLOR_DEPTH_24BIT; output_select = OUT_FROM_8BIT_BYPASS; break; } /*Config Color Depth*/ hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth)); } else if (vpara->output_color == VIDEO_OUTPUT_YCBCR422) { switch (vpara->color_depth) { case HDMI_COLOR_DEPTH_8BIT: remap_size = YCC422_16BIT; break; case HDMI_COLOR_DEPTH_10BIT: remap_size = YCC422_20BIT; break; case HDMI_COLOR_DEPTH_12BIT: remap_size = YCC422_24BIT; break; default: remap_size = YCC422_16BIT; break; } output_select = OUT_FROM_YCC422_REMAP; /*Config remap size for the different color Depth*/ hdmi_msk_reg(hdmi_dev, VP_REMAP, m_YCC422_SIZE, v_YCC422_SIZE(remap_size)); } else { hdmi_err(hdmi_drv->dev, "invalid output color type: %d", vpara->output_color); return -1; } /*Config pixel repettion*/ hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR, v_DESIRED_PR_FACTOR(vpara->pixel_repet)); if (vpara->pixel_repet > 0) hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL, v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0)); else hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL, v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1)); /*config output select*/ if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */ hdmi_msk_reg(hdmi_dev, VP_CONF, m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | m_OUTPUT_SEL, v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) | v_YCC422_EN(0) | v_OUTPUT_SEL(output_select)); } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */ hdmi_msk_reg(hdmi_dev, VP_CONF, m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | m_OUTPUT_SEL, v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) | v_YCC422_EN(1) | v_OUTPUT_SEL(output_select)); } else if (output_select == OUT_FROM_8BIT_BYPASS || output_select == 3) { /* bypass */ hdmi_msk_reg(hdmi_dev, VP_CONF, m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | m_OUTPUT_SEL, v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) | v_YCC422_EN(0) | v_OUTPUT_SEL(output_select)); } #if defined(HDMI_VIDEO_STUFFING) /* YCC422 and pixel packing stuffing*/ hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1)); hdmi_msk_reg(hdmi_dev, VP_STUFF, m_YCC422_STUFFING | m_PP_STUFFING, v_YCC422_STUFFING(1) | v_PP_STUFFING(1)); #endif return 0; }
static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara) //TODO Daisen wait to add support 3D { int h_act = 0, v_act = 0; int h_syncdelay = 0, v_syncdelay = 0; int h_sync = 0, v_sync = 0; int h_blank = 0, v_blank = 0; int vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync; int hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync; int de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0; struct fb_videomode *mode = NULL; struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); if(mode == NULL) { hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); return -ENOENT; } hdmi_drv->pixclock = mode->pixclock; switch(vpara->color_depth) { case HDMI_COLOR_DEPTH_8BIT: hdmi_drv->tmdsclk = mode->pixclock; break; case HDMI_COLOR_DEPTH_10BIT: hdmi_drv->tmdsclk = mode->pixclock * 10 / 8; break; case HDMI_COLOR_DEPTH_12BIT: hdmi_drv->tmdsclk = mode->pixclock * 12 / 8; break; case HDMI_COLOR_DEPTH_16BIT: hdmi_drv->tmdsclk = mode->pixclock * 2; break; default: hdmi_drv->tmdsclk = mode->pixclock; break; } rk3288_hdmi_config_phy(hdmi_drv, vpara->pixel_repet, vpara->color_depth); hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_ENCRYPT_BYPASS | m_HDMI_DVI, v_ENCRYPT_BYPASS(1) | v_HDMI_DVI(vpara->output_mode)); //cfg to bypass hdcp data encrypt hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL | m_FC_HDMI_DVI | m_FC_INTERLACE_MODE, v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) | v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->output_mode) | v_FC_INTERLACE_MODE(mode->vmode)); hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VBLANK, v_FC_VBLANK(mode->vmode)); h_act = mode->xres; hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(h_act >> 8)); hdmi_writel(hdmi_dev, FC_INHACTIV0, (h_act & 0xff)); v_act = mode->yres; hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(v_act >> 8)); hdmi_writel(hdmi_dev, FC_INVACTIV0, (v_act & 0xff)); h_blank = mode->hsync_len + mode->left_margin + mode->right_margin; hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(h_blank >> 8)); hdmi_writel(hdmi_dev, FC_INHBLANK0, (h_blank & 0xff)); v_blank = mode->vsync_len + mode->upper_margin + mode->lower_margin; hdmi_writel(hdmi_dev, FC_INVBLANK, (v_blank & 0xff)); h_syncdelay = mode->right_margin; hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(h_syncdelay >> 8)); hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (h_syncdelay & 0xff)); v_syncdelay = mode->lower_margin; hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (v_syncdelay & 0xff)); h_sync = mode->hsync_len; hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(h_sync >> 8)); hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (h_sync & 0xff)); v_sync = mode->vsync_len; hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (v_sync & 0xff)); /*Set the control period minimum duration(min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/ hdmi_writel(hdmi_dev, FC_CTRLDUR, 12); hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32); #if 0 if(hdmi_drv->tmdsclk > 340000000) { //used for HDMI 2.0 TX //TODO Daisen wait to modify HDCP KEEPOUT hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1)); hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1)); } /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms * worst case: tmdsClock == 25MHz => config <= 19 */ hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1); /*Set PreambleFilter*/ for (i = 0; i < 3; i++) { value = (i + 1) * 11; if (i == 0) /*channel 0*/ hdmi_writel(hdmi_dev, FC_CH0PREAM, value); else if (i == 1) /*channel 1*/ hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f); else if (i == 2) /*channel 2*/ hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f); } #endif /*Set PixelRepetition:No pixel repetition*/ hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(vpara->pixel_repet + 1)); return 0; }
int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff) { int i = 0, n = 0, index = 0, ret = -1, trytime = 2; int offset = (block % 2) * 0x80; //int interrupt = 0; //unsigned long flags; struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); hdmi_dbg(hdmi_drv->dev, "[%s] block %d\n", __FUNCTION__, block); //spin_lock_irqsave(&hdmi_drv->irq_lock, flags); hdmi_dev->i2cm_int = 0; //spin_unlock_irqrestore(&hdmi_drv->irq_lock, flags); //Set DDC I2C CLK which devided from DDC_CLK to 100KHz. hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR, 0x7a); hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR, 0x8d); hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE, v_I2CM_FAST_STD_MODE(STANDARD_MODE)); //Set Standard Mode //Enable I2C interrupt for reading edid hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, v_SCDC_READREQ_MUTE(0) | v_I2CM_DONE_MUTE(0) | v_I2CM_ERR_MUTE(0)); hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0)); hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0)); hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR); hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR); hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2); while(trytime--) { for(n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) { hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n); //enable extend sequential read operation if(block == 0) hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD8, v_I2CM_RD8(1)); else hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1)); #if 0 i = 200; while(i--) { //spin_lock_irqsave(&hdmi_drv->irq_lock, flags); interrupt = hdmi_dev->i2cm_int; hdmi_dev->i2cm_int = 0; //spin_unlock_irqrestore(&hdmi_drv->irq_lock, flags); if(interrupt & (m_SCDC_READREQ | m_I2CM_DONE | m_I2CM_ERROR)) break; msleep(5); } if((i == 0) || (interrupt & m_I2CM_ERROR)) { hdmi_err(hdmi_drv->dev, "[%s] edid read error\n", __FUNCTION__); rk3288_hdmi_i2cm_reset(hdmi_dev); break; } #endif //if(interrupt & m_I2CM_DONE) { msleep(1); for(index = 0; index < 8; index++) { buff[8 * n + index] = hdmi_readl(hdmi_dev, I2CM_READ_BUFF0 + index); } if(n == HDMI_EDID_BLOCK_SIZE / 8 - 1) { ret = 0; hdmi_dbg(hdmi_drv->dev, "[%s] edid read sucess\n", __FUNCTION__); #ifdef HDMI_DEBUG for(i = 0; i < 128; i++) { printk("%02x ,", buff[i]); if( (i + 1) % 16 == 0) printk("\n"); } #endif goto exit; } } } hdmi_err(hdmi_drv->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime); msleep(100); } exit: //Disable I2C interrupt hdmi_msk_reg(hdmi_dev, IH_MUTE_I2CM_STAT0, m_I2CM_DONE_MUTE | m_I2CM_ERR_MUTE, v_I2CM_DONE_MUTE(1) | v_I2CM_ERR_MUTE(1)); hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1)); hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1)); return ret; }
int rk30_hdmi_read_edid(int block, unsigned char *buff) { int value, ret = -1, ddc_bus_freq = 0; char interrupt = 0, trytime = 2; unsigned long flags; hdmi_dbg(hdmi->dev, "[%s] block %d\n", __FUNCTION__, block); spin_lock_irqsave(&hdmi->irq_lock, flags); edid_result = 0; spin_unlock_irqrestore(&hdmi->irq_lock, flags); //Before Phy parameter was set, DDC_CLK is equal to PLLA freq which is 30MHz. //Set DDC I2C CLK which devided from DDC_CLK to 100KHz. ddc_bus_freq = (30000000/HDMI_EDID_DDC_CLK)/4; HDMIWrReg(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); HDMIWrReg(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); // Enable edid interrupt HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS | m_INT_EDID_ERR | m_INT_EDID_READY); while(trytime--) { // Config EDID block and segment addr HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80); HDMIWrReg(EDID_SEGMENT_POINTER, block/2); value = 100; while(value--) { spin_lock_irqsave(&hdmi->irq_lock, flags); interrupt = edid_result; edid_result = 0; spin_unlock_irqrestore(&hdmi->irq_lock, flags); if(interrupt & (m_INT_EDID_ERR | m_INT_EDID_READY)) break; msleep(10); } hdmi_dbg(hdmi->dev, "[%s] edid read value %d\n", __FUNCTION__, value); if(interrupt & m_INT_EDID_READY) { for(value = 0; value < HDMI_EDID_BLOCK_SIZE; value++) buff[value] = HDMIRdReg(DDC_READ_FIFO_ADDR); ret = 0; hdmi_dbg(hdmi->dev, "[%s] edid read sucess\n", __FUNCTION__); #ifdef HDMI_DEBUG for(value = 0; value < 128; value++) { printk("%02x ,", buff[value]); if( (value + 1) % 16 == 0) printk("\n"); } #endif break; } if(interrupt & m_INT_EDID_ERR) hdmi_err(hdmi->dev, "[%s] edid read error\n", __FUNCTION__); hdmi_dbg(hdmi->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime); msleep(100); } // Disable edid interrupt HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS); return ret; }
int rk30_hdmi_config_audio(struct hdmi_audio *audio) { int value, rate, N; char word_length, channel; if(audio->channel < 3) channel = I2S_CHANNEL_1_2; else if(audio->channel < 5) channel = I2S_CHANNEL_3_4; else if(audio->channel < 7) channel = I2S_CHANNEL_5_6; else channel = I2S_CHANNEL_7_8; switch(audio->rate) { case HDMI_AUDIO_FS_32000: rate = AUDIO_32K; N = N_32K; break; case HDMI_AUDIO_FS_44100: rate = AUDIO_441K; N = N_441K; break; case HDMI_AUDIO_FS_48000: rate = AUDIO_48K; N = N_48K; break; case HDMI_AUDIO_FS_88200: rate = AUDIO_882K; N = N_882K; break; case HDMI_AUDIO_FS_96000: rate = AUDIO_96K; N = N_96K; break; case HDMI_AUDIO_FS_176400: rate = AUDIO_1764K; N = N_1764K; break; case HDMI_AUDIO_FS_192000: rate = AUDIO_192K; N = N_192K; break; default: hdmi_err(hdmi->dev, "[%s] not support such sample rate %d\n", __FUNCTION__, audio->rate); return -ENOENT; } // switch(audio->word_length) // { // case HDMI_AUDIO_WORD_LENGTH_16bit: // word_length = 0x02; // break; // case HDMI_AUDIO_WORD_LENGTH_20bit: // word_length = 0x0a; // break; // case HDMI_AUDIO_WORD_LENGTH_24bit: // word_length = 0x0b; // break; // default: // hdmi_err(hdmi->dev, "[%s] not support such word length %d\n", __FUNCTION__, audio->word_length); // return -ENOENT; // } //set_audio_if I2S HDMIWrReg(AUDIO_CTRL1, 0x00); //internal CTS, disable down sample, i2s input, disable MCLK HDMIWrReg(AUDIO_CTRL2, 0x40); HDMIWrReg(I2S_AUDIO_CTRL, v_I2S_MODE(I2S_MODE_STANDARD) | v_I2S_CHANNEL(channel) ); HDMIWrReg(I2S_INPUT_SWAP, 0x00); //no swap HDMIMskReg(value, AV_CTRL1, m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate)) // HDMIWrReg(SRC_NUM_AUDIO_LEN, word_length); //Set N value 6144, fs=48kHz HDMIWrReg(N_1, N & 0xFF); HDMIWrReg(N_2, (N >> 8) & 0xFF); HDMIWrReg(LR_SWAP_N3, (N >> 16) & 0x0F); rk30_hdmi_config_aai(); return 0; }
int rk30_hdmi_config_video(struct hdmi_video_para *vpara) { int value; struct fb_videomode *mode; hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); if(vpara == NULL) { hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); return -1; } if(hdmi->pwr_mode == PWR_SAVE_MODE_E) rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); if(hdmi->pwr_mode == PWR_SAVE_MODE_D || hdmi->pwr_mode == PWR_SAVE_MODE_A) rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); // Input video mode is RGB24bit, Data enable signal from external HDMIMskReg(value, AV_CTRL1, m_INPUT_VIDEO_MODE | m_DE_SIGNAL_SELECT, \ v_INPUT_VIDEO_MODE(vpara->input_mode) | EXTERNAL_DE) HDMIMskReg(value, VIDEO_CTRL1, m_VIDEO_OUTPUT_MODE | m_VIDEO_INPUT_DEPTH | m_VIDEO_INPUT_COLOR_MODE, \ v_VIDEO_OUTPUT_MODE(vpara->output_color) | v_VIDEO_INPUT_DEPTH(VIDEO_INPUT_DEPTH_8BIT) | vpara->input_color) HDMIWrReg(DEEP_COLOR_MODE, 0x20); // color space convert rk30_hdmi_config_csc(vpara); // Set HDMI Mode HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); // Set ext video mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); if(mode == NULL) { hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); return -ENOENT; } hdmi->tmdsclk = mode->pixclock; if( (vpara->vic == HDMI_720x480p_60Hz_4_3) || (vpara->vic == HDMI_720x480p_60Hz_16_9) ) value = v_VSYNC_OFFSET(6); else value = v_VSYNC_OFFSET(0); value |= v_EXT_VIDEO_ENABLE(1) | v_INTERLACE(mode->vmode); if(mode->sync & FB_SYNC_HOR_HIGH_ACT) value |= v_HSYNC_POLARITY(1); if(mode->sync & FB_SYNC_VERT_HIGH_ACT) value |= v_VSYNC_POLARITY(1); HDMIWrReg(EXT_VIDEO_PARA, value); value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->right_margin + mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HBLANK_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HBLANK_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HDELAY_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HDELAY_H, (value >> 8) & 0xFF); value = mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->vsync_len + mode->lower_margin; HDMIWrReg(EXT_VIDEO_PARA_VBLANK_L, value & 0xFF); if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9) value = 42; else value = mode->upper_margin + mode->vsync_len; HDMIWrReg(EXT_VIDEO_PARA_VDELAY, value & 0xFF); value = mode->vsync_len; HDMIWrReg(EXT_VIDEO_PARA_VSYNCWIDTH, value & 0xFF); if(vpara->output_mode == OUTPUT_HDMI) { rk30_hdmi_config_avi(vpara->vic, vpara->output_color); hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); } else { hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); } rk30_hdmi_config_phy(vpara->vic); rk30_hdmi_control_output(0); return 0; }
static int rk2928_hdmi_config_video(struct hdmi_video_para *vpara) { int value; struct fb_videomode *mode; hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); if(vpara == NULL) { hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); return -1; } if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); // Diable video and audio output HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); // Input video mode is SDR RGB24bit, Data enable signal from external HDMIWrReg(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); HDMIWrReg(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | (vpara->output_color & 0xFF)); // Set HDMI Mode HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); // Enable or disalbe color space convert if(vpara->input_color != vpara->output_color) { value = v_SOF_DISABLE | v_CSC_ENABLE; } else value = v_SOF_DISABLE; HDMIWrReg(VIDEO_CONTRL3, value); // Set ext video #if 1 HDMIWrReg(VIDEO_TIMING_CTL, 0); mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); if(mode == NULL) { hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); return -ENOENT; } hdmi->tmdsclk = mode->pixclock; #else value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); if(mode->sync & FB_SYNC_HOR_HIGH_ACT) value |= v_HSYNC_POLARITY(1); if(mode->sync & FB_SYNC_VERT_HIGH_ACT) value |= v_VSYNC_POLARITY(1); HDMIWrReg(VIDEO_TIMING_CTL, value); value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HTOTAL_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->right_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HBLANK_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HDELAY_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); value = mode->hsync_len; HDMIWrReg(VIDEO_EXT_HDURATION_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; HDMIWrReg(VIDEO_EXT_VTOTAL_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->vsync_len + mode->lower_margin; HDMIWrReg(VIDEO_EXT_VBLANK, value & 0xFF); if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9) value = 42; else value = mode->upper_margin + mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDELAY, value & 0xFF); value = mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF); #endif if(vpara->output_mode == OUTPUT_HDMI) { rk2928_hdmi_config_avi(vpara->vic, vpara->output_color); hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); } else { hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); } return 0; }
int cat66121_hdmi_sys_config_video(struct hdmi_video_para *vpara) { struct fb_videomode *mode; HDMI_Aspec aspec ; HDMI_Colorimetry Colorimetry ; VIDEOPCLKLEVEL level ; if(vpara == NULL) { hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); return -1; } // output Color mode switch(vpara->output_color) { case HDMI_COLOR_YCbCr444: bOutputColorMode = F_MODE_YUV444 ; break ; case HDMI_COLOR_YCbCr422: bOutputColorMode = F_MODE_YUV422 ; break ; case HDMI_COLOR_RGB: default: bOutputColorMode = F_MODE_RGB444 ; break ; } // Set ext video mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); if(mode == NULL) { hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); return -ENOENT; } hdmi->tmdsclk = mode->pixclock; switch(vpara->vic) { case HDMI_640x480p60: pixelrep = 0 ; aspec = HDMI_4x3 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_480p60: pixelrep = 0 ; aspec = HDMI_4x3 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_480p60_16x9: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_720p60: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_1080i60: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_480i60: pixelrep = 1 ; aspec = HDMI_4x3 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_480i60_16x9: pixelrep = 1 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_1080p60: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_576p50: pixelrep = 0 ; aspec = HDMI_4x3 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_576p50_16x9: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_720p50: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_1080i50: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_576i50: pixelrep = 1 ; aspec = HDMI_4x3 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_576i50_16x9: pixelrep = 1 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU601 ; break ; case HDMI_1080p50: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_1080p24: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_1080p25: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_1080p30: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; break ; case HDMI_720p30: pixelrep = 0 ; aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; default: aspec = HDMI_16x9 ; Colorimetry = HDMI_ITU709 ; } if( Colorimetry == HDMI_ITU709 ) { bInputColorMode |= F_VIDMODE_ITU709 ; } else { bInputColorMode &= ~F_VIDMODE_ITU709 ; } if( vpara->vic != HDMI_640x480p60) { bInputColorMode |= F_VIDMODE_16_235 ; } else { bInputColorMode &= ~F_VIDMODE_16_235 ; } if( (hdmi->tmdsclk*(pixelrep+1))>80000000L ) { level = PCLK_HIGH ; } else if((hdmi->tmdsclk*(pixelrep+1))>20000000L) { level = PCLK_MEDIUM ; } else { level = PCLK_LOW ; } HDMITX_EnableVideoOutput(level,bInputColorMode,bOutputColorMode ,vpara->output_mode); if(vpara->output_mode == OUTPUT_HDMI) { cat66121_sys_config_avi(vpara->vic, bOutputColorMode, aspec, Colorimetry, pixelrep); #ifdef OUTPUT_3D_MODE ConfigfHdmiVendorSpecificInfoFrame(OUTPUT_3D_MODE); #endif } else { HDMITX_EnableAVIInfoFrame(FALSE ,NULL); HDMITX_EnableVSInfoFrame(FALSE,NULL); } setHDMITX_VideoSignalType(INPUT_SIGNAL_TYPE); #ifdef SUPPORT_SYNCEMBEDDED if(INPUT_SIGNAL_TYPE & T_MODE_SYNCEMB) { setHDMITX_SyncEmbeddedByVIC(vpara->vic,INPUT_SIGNAL_TYPE); } #endif return HDMI_ERROR_SUCESS; }