On Thu, Oct 19, 2017 at 12:39 AM, Hans Verkuil <hverkuil@xxxxxxxxx> wrote: <snip> >>> What I am missing here is handling of the RGB quantization range. >>> An HDMI receiver will typically send full range RGB or limited range YUV >>> to the SoC. The HDMI source can however send full or limited range RGB >>> or limited range YUV (full range YUV is theoretically possible, but nobody >>> does that). >>> >> >> isn't this quantization range a function of the colorspace and >> colorimetry dictated by the AVI infoframe? I'm taking these into >> consideration when setting up the conversion matrix in >> tda1997x_configure_conv(). > > No, it's independent of that. and from another reply: > A small correction here: while ideally you should indeed check if the current > EDID supports selectable RGB Quantization Range, in practice you don't need > to. If the source explicitly sets the RGB quantization range, then just use > that. > > Note: some hardware can do this automatically (adv7604) by detecting what is > transmitted in the AVI InfoFrame. That's probably not the case here since you > have to provide a conversion matrix. I see the AVI infoframe has hdmi_quantization_range and hdmi_ycc_quantization_range along with vid_code. I'm not at all clear what to do with this information. Is there anything you see in the datasheet [1] that points to something I need to be doing? > >> >>> For a Full HD receiver the rules when receiving RGB video are as follows: >>> >>> If the EDID supports selectable RGB Quantization Range, then check if the >>> source explicitly sets the RGB quantization range in the AVI InfoFrame and >>> use that value. >>> >>> Otherwise fall back to the default rules: >>> >>> if VIC == 0, then expect full range RGB, otherwise expect limited range RGB. >> >> Are you referring to the video_code field of the AVI infoframe or vic >> from a vendor infoframe? > > AVI InfoFrame. > > The HDMI VIC codes in the vendor InfoFrame are only valid for 4k formats. And > that's not supported by this device, right? Right, the TDA1997x supports 1080p only. > >> >>> >>> It gets even more complicated with 4k video, but this is full HD only. >>> >>> In addition, you may also want to implement the V4L2_CID_DV_RX_RGB_RANGE control >>> to let userspace override the autodetection. >> >> I'll add that as an additional patch. Are there other V4L2_CID's that >> I should be adding here? > > V4L2_CID_DV_RX_POWER_PRESENT (if possible) and optionally V4L2_CID_DV_RX_IT_CONTENT_TYPE. > It looks like there is a register for 5V_HPD detect. I assume the content type to return is the value reported from the AVI frame? <snip> >> >> Regarding video standard detection where this chip provides me with >> vertical-period, horizontal-period, and horizontal-pulse-width I >> should be able to detect the standard simply based off of >> vertical-period (framerate) and horizontal-period (line width >> including blanking) right? I wasn't sure if my method of matching >> these within 14% tolerance made sense. I will be removing the hsmatch >> logic from that as it seems the horizontal-pulse-width should be >> irrelevant. > > For proper video detection you ideally need: > > h/v sync size > h/v back/front porch size > h/v polarity > pixelclock (usually an approximation) > > The v4l2_find_dv_timings_cap() helper can help you find the corresponding > timings, allowing for pixelclock variation. > > That function assumes that the sync/back/frontporch values are all known. > But not all devices can actually discover those values. What can your > hardware detect? Can it tell front and backporch apart? Can it determine > the sync size? > > I've been considering for some time to improve that helper function to be > able to handle hardware that isn't able separate sync/back/frontporch values. > The TDA1997x provides only the vertical/horizontal periods and the horizontal pulse width (section 8.3.4 of datasheet [1]). Can you point me to a good primer on the relationship between these values and the h/v back/front porch? Currently I iterate over the list of known formats calculating hper (bt->pixelclock / V4L2_DV_BT_FRAME_WIDTH(bt)) and vper (hper / V4L2_DV_BT_FRAME_HEIGHT(bt)) (framerate) and find the closest match within +/- 7% tolerance. The list of supported formats is sorted by framerate then width. /* look for matching timings */ for (i = 0; i < ARRAY_SIZE(tda1997x_hdmi_modes); i++) { const struct tda1997x_video_std *std = &tda1997x_hdmi_modes[i]; const struct v4l2_bt_timings *bt = &std->timings.bt; int _hper, _vper, _hsper; int vmin, vmax, hmin, hmax, hsmin, hsmax; int vmatch, hsmatch; width = V4L2_DV_BT_FRAME_WIDTH(bt); lines = V4L2_DV_BT_FRAME_HEIGHT(bt); _hper = (int)bt->pixelclock / (int)width; _vper = _hper / lines; _hsper = (int)bt->pixelclock / (int)bt->hsync; if (bt->interlaced) _vper *= 2; /* vper +/- 0.7% */ vmin = 993 * (27000000 / _vper) / 1000; vmax = 1007 * (27000000 / _vper) / 1000; _hsper = (int)bt->pixelclock / (int)bt->hsync; if (bt->interlaced) _vper *= 2; /* vper +/- 0.7% */ vmin = 993 * (27000000 / _vper) / 1000; vmax = 1007 * (27000000 / _vper) / 1000; /* hper +/- 0.7% */ hmin = 993 * (27000000 / _hper) / 1000; hmax = 1007 * (27000000 / _hper) / 1000; /* vmatch matches the framerate */ vmatch = ((vper <= vmax) && (vper >= vmin)) ? 1 : 0; /* hmatch matches the width */ hmatch = ((hper <= hmax) && (hper >= hmin)) ? 1 : 0; if (vmatch && hsmatch) { v4l_info(state->client, "resolution: %dx%d%c@%d (%d/%d/%d) %dMHz %d\n", bt->width, bt->height, bt->interlaced?'i':'p', _vper, vper, hper, hsper, pixrate, hsmatch); state->fps = (int)bt->pixelclock / (width * lines); state->std = std; return 0; } } Note that I've thrown out any comparisons based on horizontal pulse width from my first patch as that didn't appear to fit well. So far the above works well however I do fail to recognize the following modes (using a Marshall SG4K HDMI test generator): VESA640x480P_60HZ v4l2 defines this as 4L2_DV_BT_CEA_640X480P59_94 which fails vmatch VESA1400x1050P_60HZ should match V4L2_DV_BT_DMT_1400X1050P60_RB but it calculates 59Hz and fails vmatch VESA1920x1200P_60HZ should match V4L2_DV_BT_DMT_1920X1200P60_RB but it calculates 59Hz and fails vmatch CEAVIC1440x480I_60HZ not in v4l2-dv-timings.h CEAVIC720x480P_60HZ not in v4l2-dv-timings.h (there's a 720x480p59) CEAVIC1440x576I_50HZ not in v4l2-dv-timings.h I should have mentioned in my cover letter that I only have a datasheet for this device and some fairly obfuscated vendor example code - I don't have proper register set documentation. Regards, Tim [1] http://dev.gateworks.com/datasheets/TDA19971-datasheet-rev3.pdf