/** * Check Video parameters against allowed values and read EDID structure * to ensure compatibility with sink. * @param video video parameters */ static int api_CheckParamsVideo(videoParams_t * video) { u8 errorCode = TRUE; hdmivsdb_t vsdb; dtd_t dtd; unsigned i = 0; shortVideoDesc_t svd; videoCapabilityDataBlock_t capability; int valid = FALSE; colorimetryDataBlock_t colorimetry; LOG_TRACE(); colorimetryDataBlock_Reset(&colorimetry); shortVideoDesc_Reset(&svd); dtd_Fill(&dtd, 1, 60000); videoCapabilityDataBlock_Reset(&capability); if (videoParams_GetHdmi(video)) { /* HDMI mode */ if (api_EdidHdmivsdb(&vsdb) == TRUE) { if (videoParams_GetColorResolution(video) == 10 && !hdmivsdb_GetDeepColor30(&vsdb)) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_30BIT_DC); printk("Sink does NOT support 30bits/pixel deep colour mode"); errorCode = FALSE; } else if (videoParams_GetColorResolution(video) == 12 && !hdmivsdb_GetDeepColor36(&vsdb)) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_36BIT_DC); printk("Sink does NOT support 36bits/pixel deep colour mode"); errorCode = FALSE; } else if (videoParams_GetColorResolution(video) == 16 && !hdmivsdb_GetDeepColor48(&vsdb)) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_48BIT_DC); printk("Sink does NOT support 48bits/pixel deep colour mode"); errorCode = FALSE; } if (videoParams_GetEncodingOut(video) == YCC444 && !hdmivsdb_GetDeepColorY444(&vsdb)) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC444_DC); printk("Sink does NOT support YCC444 in deep colour mode"); errorCode = FALSE; } if (videoParams_GetTmdsClock(video) > 16500) { /* * Sink must specify MaxTMDSClk when supports frequencies over 165MHz * GetMaxTMDSClk() is TMDS clock / 5MHz and GetTmdsClock() returns [0.01MHz] * so GetMaxTMDSClk() value must be multiplied by 500 in order to be compared */ if (videoParams_GetTmdsClock(video) > (hdmivsdb_GetMaxTmdsClk( &vsdb) * 500)) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_TMDS_CLOCK); LOG_WARNING2("Sink does not support TMDS clock", videoParams_GetTmdsClock(video)); LOG_WARNING2("Maximum TMDS clock supported is", hdmivsdb_GetMaxTmdsClk(&vsdb) * 500); errorCode = FALSE; } } } else { error_Set(ERR_SINK_DOES_NOT_SUPPORT_HDMI); printk("Sink does not support HDMI"); errorCode = FALSE; } /* video out encoding (YCC/RGB) */ if (videoParams_GetEncodingOut(video) == YCC444 && !api_EdidSupportsYcc444()) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC444_ENCODING); printk("Sink does NOT support YCC444 encoding"); errorCode = FALSE; } else if (videoParams_GetEncodingOut(video) == YCC422 && !api_EdidSupportsYcc422()) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC422_ENCODING); printk("Sink does NOT support YCC422 encoding"); errorCode = FALSE; } /* check extended colorimetry data and if supported by sink */ if (videoParams_GetColorimetry(video) == EXTENDED_COLORIMETRY) { if (api_EdidColorimetryDataBlock(&colorimetry) == TRUE) { if (!colorimetryDataBlock_SupportsXvYcc601(&colorimetry) && videoParams_GetExtColorimetry(video) == 0) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_XVYCC601_COLORIMETRY); printk("Sink does NOT support xvYcc601 extended colorimetry"); errorCode = FALSE; } else if (!colorimetryDataBlock_SupportsXvYcc709(&colorimetry) && videoParams_GetExtColorimetry(video) == 1) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_XVYCC709_COLORIMETRY); printk("Sink does NOT support xvYcc709 extended colorimetry"); errorCode = FALSE; } else { error_Set(ERR_EXTENDED_COLORIMETRY_PARAMS_INVALID); printk("Invalid extended colorimetry parameters"); errorCode = FALSE; } } else { error_Set(ERR_SINK_DOES_NOT_SUPPORT_EXTENDED_COLORIMETRY); errorCode = FALSE; } } } else { /* DVI mode */ if (videoParams_GetColorResolution(video) > 8) { error_Set(ERR_COLOR_DEPTH_NOT_SUPPORTED); printk("DVI - deep color not supported"); errorCode = FALSE; } if (videoParams_GetEncodingOut(video) != RGB) { error_Set(ERR_DVI_MODE_WITH_YCC_ENCODING); printk("DVI mode does not support video encoding other than RGB"); errorCode = FALSE; } if (videoParams_IsPixelRepetition(video)) { error_Set(ERR_DVI_MODE_WITH_PIXEL_REPETITION); printk("DVI mode does not support pixel repetition"); errorCode = FALSE; } if (videoParams_GetTmdsClock(video) > 16500) { printk("Sink must support DVI dual-link"); } /* check colorimetry data */ if ((videoParams_GetColorimetry(video) == EXTENDED_COLORIMETRY)) { error_Set(ERR_DVI_MODE_WITH_EXTENDED_COLORIMETRY); printk("DVI does not support extended colorimetry"); errorCode = FALSE; } } /* * DTD check * always checking VALID to minimise code execution (following probability) * this video code is to be supported by all dtv's */ valid = (dtd_GetCode(videoParams_GetDtd(video)) == 1) ? TRUE : FALSE; if (!valid) { for (i = 0; i < api_EdidDtdCount(); i++) { api_EdidDtd(i, &dtd); if (dtd_GetCode(videoParams_GetDtd(video)) != (u8) (-1)) { if (dtd_GetCode(videoParams_GetDtd(video)) == dtd_GetCode(&dtd)) { valid = TRUE; break; } } else if (dtd_IsEqual(videoParams_GetDtd(video), &dtd)) { valid = TRUE; break; } } } if (!valid) { if (dtd_GetCode(videoParams_GetDtd(video)) != (u8) (-1)) { for (i = 0; i < api_EdidSvdCount(); i++) { api_EdidSvd(i, &svd); if ((unsigned) (dtd_GetCode(videoParams_GetDtd(video))) == shortVideoDesc_GetCode(&svd)) { valid = TRUE; break; } } } } if (!valid) { error_Set(ERR_SINK_DOES_NOT_SUPPORT_SELECTED_DTD); printk("Sink does NOT indicate support for selected DTD"); errorCode = FALSE; } /* check quantization range */ if (api_EdidVideoCapabilityDataBlock(&capability) == TRUE) { if (!videoCapabilityDataBlock_GetQuantizationRangeSelectable( &capability) && videoParams_GetRgbQuantizationRange(video) > 1) { printk("Sink does NOT indicate support for selected quantization range"); } } return errorCode; }
int api_Configure(videoParams_t * video, audioParams_t * audio, productParams_t * product, hdcpParams_t * hdcp) { hdmivsdb_t vsdb; // int audioOn = 0; //lltang audio on int audioOn = 1; int success = TRUE; int hdcpOn = (hdcp != 0 && (control_SupportsHdcp(api_mBaseAddress) == TRUE)) ? TRUE : FALSE; LOG_TRACE(); if (video == NULL) { error_Set(ERR_HPD_LOST); LOG_ERROR("video params invalid"); return FALSE; } audioOn = (audio != 0 && videoParams_GetHdmi(video)); if (api_mCurrentState < API_HPD) { error_Set(ERR_HPD_LOST); LOG_ERROR("cable not connected"); return FALSE; } else if (api_mCurrentState == API_HPD) { printk("E-EDID not read. Media may not be supported by sink\n"); } else if (api_mCurrentState == API_EDID_READ) { api_CheckParamsVideo(video); if (api_EdidHdmivsdb(&vsdb)) { if (!hdmivsdb_GetDeepColor30(&vsdb) && !hdmivsdb_GetDeepColor36(&vsdb) && !hdmivsdb_GetDeepColor48(&vsdb)) { videoParams_SetColorResolution(video, 0); } } } control_InterruptMute(api_mBaseAddress, ~0); /* disable interrupts */ #ifdef CONFIG_HMDI_JZ4780_DEBUG printk("=====>disable TX_INT in %s:%d\n", __func__, __LINE__); #endif system_InterruptDisable(TX_INT); do { if (video_Configure(api_mBaseAddress, video, api_mDataEnablePolarity, hdcpOn) != TRUE) { success = FALSE; break; } if (audioOn) { if (api_mCurrentState == API_EDID_READ) { api_CheckParamsAudio(audio); } #if 0 //del by lltang if (board_AudioClock(api_mBaseAddress, audioParams_AudioClock(audio)) != TRUE) { success = FALSE; break; } #endif if (audio_Configure(api_mBaseAddress, audio, videoParams_GetPixelClock( video), videoParams_GetRatioClock(video)) != TRUE) { success = FALSE; break; } packets_AudioInfoFrame(api_mBaseAddress, audio); } else if (audio != 0 && videoParams_GetHdmi(video) != TRUE) { printk("DVI mode selected: audio not configured\n"); } else { printk("No audio parameters provided: not configured\n"); } if (videoParams_GetHdmi(video) == TRUE) { if (packets_Configure(api_mBaseAddress, video, product) != TRUE) { success = FALSE; break; } api_mSendGamutOk = (videoParams_GetEncodingOut(video) == YCC444) || (videoParams_GetEncodingOut(video) == YCC422); api_mSendGamutOk = api_mSendGamutOk && (videoParams_GetColorimetry( video) == EXTENDED_COLORIMETRY); } else { printk("DVI mode selected: packets not configured\n"); } if (hdcpOn == TRUE) { /* HDCP is PHY independent */ if (hdcp_Configure(api_mBaseAddress, hdcp, videoParams_GetHdmi(video), dtd_GetHSyncPolarity(videoParams_GetDtd(video)), dtd_GetVSyncPolarity(videoParams_GetDtd(video))) == FALSE) { printk("HDCP not configured\n"); hdcpOn = FALSE; success = FALSE; break; } } else if (hdcp != 0 && control_SupportsHdcp(api_mBaseAddress) != TRUE) { printk("HDCP is not supported by hardware\n"); } else { printk("No HDCP parameters provided: not configured\n"); } if (board_PixelClock(api_mBaseAddress, videoParams_GetPixelClock(video), videoParams_GetColorResolution(video)) != TRUE) { success = FALSE; break; } if (control_Configure(api_mBaseAddress, videoParams_GetPixelClock(video), videoParams_GetPixelRepetitionFactor(video), videoParams_GetColorResolution(video), videoParams_IsColorSpaceConversion(video), audioOn, FALSE, hdcpOn) != TRUE) { success = FALSE; break; } if (phy_Configure(api_mBaseAddress, videoParams_GetPixelClock(video), videoParams_GetColorResolution(video), videoParams_GetPixelRepetitionFactor(video)) != TRUE) { success = FALSE; break; } /* disable blue screen transmission after turning on all necessary blocks (e.g. HDCP) */ if (video_ForceOutput(api_mBaseAddress, FALSE) != TRUE) { success = FALSE; break; } /* reports HPD state to HDCP */ if (hdcpOn) { hdcp_RxDetected(api_mBaseAddress, phy_HotPlugDetected( api_mBaseAddress)); } /* send AVMUTE CLEAR (optional) */ api_mCurrentState = API_CONFIGURED; } while(0); control_InterruptMute(api_mBaseAddress, 0); /* enable interrupts */ #ifdef CONFIG_HMDI_JZ4780_DEBUG printk("hdmi enable TX_INT in %s:%d\n", __func__, __LINE__); #endif system_InterruptEnable(TX_INT); return success; }
void packets_AuxiliaryVideoInfoFrame(u16 baseAddr, videoParams_t *videoParams) { u16 endTop = 0; u16 startBottom = 0; u16 endLeft = 0; u16 startRight = 0; LOG_TRACE(); if (videoParams_GetEncodingOut(videoParams) == RGB) { halFrameComposerAvi_RgbYcc(baseAddr + FC_BASE_ADDR, 0); } else if (videoParams_GetEncodingOut(videoParams) == YCC422) { halFrameComposerAvi_RgbYcc(baseAddr + FC_BASE_ADDR, 1); } else if (videoParams_GetEncodingOut(videoParams) == YCC444) { halFrameComposerAvi_RgbYcc(baseAddr + FC_BASE_ADDR, 2); } halFrameComposerAvi_ScanInfo(baseAddr + FC_BASE_ADDR, videoParams_GetScanInfo(videoParams)); if (dtd_GetHImageSize(videoParams_GetDtd(videoParams)) != 0 || dtd_GetVImageSize(videoParams_GetDtd(videoParams)) != 0) { u8 pic = (dtd_GetHImageSize(videoParams_GetDtd(videoParams)) * 10) % dtd_GetVImageSize(videoParams_GetDtd(videoParams)); halFrameComposerAvi_PicAspectRatio(baseAddr + FC_BASE_ADDR, (pic > 5) ? 2 : 1); /* 16:9 or 4:3 */ } else { halFrameComposerAvi_PicAspectRatio(baseAddr + FC_BASE_ADDR, 0); /* No Data */ } halFrameComposerAvi_IsItContent(baseAddr + FC_BASE_ADDR, videoParams_GetItContent( videoParams)); halFrameComposerAvi_QuantizationRange(baseAddr + FC_BASE_ADDR, videoParams_GetRgbQuantizationRange(videoParams)); halFrameComposerAvi_NonUniformPicScaling(baseAddr + FC_BASE_ADDR, videoParams_GetNonUniformScaling(videoParams)); if (dtd_GetCode(videoParams_GetDtd(videoParams)) != (u8) (-1)) { halFrameComposerAvi_VideoCode(baseAddr + FC_BASE_ADDR, dtd_GetCode( videoParams_GetDtd(videoParams))); } else { halFrameComposerAvi_VideoCode(baseAddr + FC_BASE_ADDR, 0); } if (videoParams_GetColorimetry(videoParams) == EXTENDED_COLORIMETRY) { /* ext colorimetry valid */ if (videoParams_GetExtColorimetry(videoParams) != (u8) (-1)) { halFrameComposerAvi_ExtendedColorimetry(baseAddr + FC_BASE_ADDR, videoParams_GetExtColorimetry(videoParams)); halFrameComposerAvi_Colorimetry(baseAddr + FC_BASE_ADDR, videoParams_GetColorimetry(videoParams)); /* EXT-3 */ } else { halFrameComposerAvi_Colorimetry(baseAddr + FC_BASE_ADDR, 0); /* No Data */ } } else { halFrameComposerAvi_Colorimetry(baseAddr + FC_BASE_ADDR, videoParams_GetColorimetry( videoParams)); /* NODATA-0/ 601-1/ 709-2/ EXT-3 */ } if (videoParams_GetActiveFormatAspectRatio(videoParams) != 0) { halFrameComposerAvi_ActiveFormatAspectRatio(baseAddr + FC_BASE_ADDR, videoParams_GetActiveFormatAspectRatio(videoParams)); halFrameComposerAvi_ActiveAspectRatioValid(baseAddr + FC_BASE_ADDR, 1); } else { halFrameComposerAvi_ActiveAspectRatioValid(baseAddr + FC_BASE_ADDR, 0); } if (videoParams_GetEndTopBar(videoParams) != (u16) (-1) || videoParams_GetStartBottomBar(videoParams) != (u16) (-1)) { if (videoParams_GetEndTopBar(videoParams) != (u16) (-1)) { endTop = videoParams_GetEndTopBar(videoParams); } if (videoParams_GetStartBottomBar(videoParams) != (u16) (-1)) { startBottom = videoParams_GetStartBottomBar(videoParams); } halFrameComposerAvi_HorizontalBars(baseAddr + FC_BASE_ADDR, endTop, startBottom); halFrameComposerAvi_HorizontalBarsValid(baseAddr + FC_BASE_ADDR, 1); } else { halFrameComposerAvi_HorizontalBarsValid(baseAddr + FC_BASE_ADDR, 0); } if (videoParams_GetEndLeftBar(videoParams) != (u16) (-1) || videoParams_GetStartRightBar(videoParams) != (u16) (-1)) { if (videoParams_GetEndLeftBar(videoParams) != (u16) (-1)) { endLeft = videoParams_GetEndLeftBar(videoParams); } if (videoParams_GetStartRightBar(videoParams) != (u16) (-1)) { startRight = videoParams_GetStartRightBar(videoParams); } halFrameComposerAvi_VerticalBars(baseAddr + FC_BASE_ADDR, endLeft, startRight); halFrameComposerAvi_VerticalBarsValid(baseAddr + FC_BASE_ADDR, 1); } else { halFrameComposerAvi_VerticalBarsValid(baseAddr + FC_BASE_ADDR, 0); } halFrameComposerAvi_OutPixelRepetition(baseAddr + FC_BASE_ADDR, (dtd_GetPixelRepetitionInput(videoParams_GetDtd(videoParams)) + 1) * (videoParams_GetPixelRepetitionFactor(videoParams) + 1) - 1); }