Hi there
We are having similar problems when connecting a UHD TV (Samsung UE40HU6900S) to the HDMI Out of the Jetson TX1.
At the first boot, the monitor was working (at a low resolution). But now at every boot the kernel booting process halts after trying to set a very high pixel clock (e.g. 594 MHz). The boot process does not get finished and we can not interact with the device at this point.
When the TV is not plugged in, the kernel boots without problems.
Error messages when kernel stops (with TV plugged in):
[ 5.536821] tegradc tegradc.1: nominal-pclk:594000000 parent:594000000 div:1.0 pclk:594000000 588060000~647460000
[ 5.920135] tegradc tegradc.1: probed
[ 5.922938] tegradc tegradc.1: nominal-pclk:594177000 parent:594000000 div:1.0 pclk:594000000 588235230~647652930
[ 6.014720] Console: switching to colour frame buffer device 480x135
[ 6.122410] tegradc tegradc.1: fb registered
..
We had similar problems with the Jetson TK1 with L4T R21.3 in May (see https://devtalk.nvidia.com/default/topic/830170/tk1-kernel-stops-booting-if-uhd-monitor-is-conected-to-hdmi/)
What seems to be the problem is the implementation of the framebuffer function tegra_fb_update_monspecs(…) in drivers/video/tegra/fb.c
In there the different video modes that are supported by the monitor get are passed to the frame buffer. Unfortunately the implementation that is used in L4T R23.1 fails to choose a working video mode.
We were able to fix the problem by using the following implementation of the tegra_fb_update_monspecs(…) function in drivers/video/tegra/fb.c and recompiling the L4T R23.1 kernel.
void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info,
struct fb_monspecs *specs,
bool (*mode_filter)(const struct tegra_dc *dc,
struct fb_videomode *mode))
{
struct fb_event event;
int i;
int blank = FB_BLANK_UNBLANK;
struct fb_videomode *bestMode;
struct tegra_dc_mode dcmode;
mutex_lock(&fb_info->info->lock);
fb_destroy_modedb(fb_info->info->monspecs.modedb);
fb_destroy_modelist(&fb_info->info->modelist);
event.info = fb_info->info;
event.data = ␣
/* Notify layers above fb.c that the hardware is unavailable */
fb_info->info->state = FBINFO_STATE_SUSPENDED;
if (specs == NULL) {
memset(&fb_info->info->monspecs, 0x0,
sizeof(fb_info->info->monspecs));
/*
* reset video mode properties to prevent garbage being
* displayed on 'mode' device.
*/
fb_info->info->mode = (struct fb_videomode*) NULL;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
blank = FB_BLANK_POWERDOWN;
console_lock();
fb_add_videomode(&tegra_dc_vga_mode, &fb_info->info->modelist);
fb_videomode_to_var(&fb_info->info->var, &tegra_dc_vga_mode);
fb_notifier_call_chain(FB_EVENT_BLANK, &event);
console_unlock();
#endif
/* For L4T - After the next hotplug, framebuffer console will
* use the old variable screeninfo by default, only video-mode
* settings will be overwritten as per monitor connected.
*/
#ifndef CONFIG_FRAMEBUFFER_CONSOLE
memset(&fb_info->info->var, 0x0, sizeof(fb_info->info->var));
#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
mutex_unlock(&fb_info->info->lock);
return;
}
memcpy(&fb_info->info->monspecs, specs,
sizeof(fb_info->info->monspecs));
fb_info->info->mode = specs->modedb;
for (i = 0; i < specs->modedb_len; i++) {
if (mode_filter) {
if (mode_filter(fb_info->win.dc, &specs->modedb[i]))
fb_add_videomode(&specs->modedb[i],
&fb_info->info->modelist);
} else {
fb_add_videomode(&specs->modedb[i],
&fb_info->info->modelist);
}
}
/* Restoring to state running. */
fb_info->info->state = FBINFO_STATE_RUNNING;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
/*
console_lock();
tegra_dc_set_fb_mode(fb_info->win.dc, specs->modedb, false);
fb_videomode_to_var(&fb_info->info->var, &specs->modedb[0]);
fb_notifier_call_chain(FB_EVENT_MODE_CHANGE_ALL, &event);
fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
fb_notifier_call_chain(FB_EVENT_BLANK, &event);
console_unlock();
*/
// WORKAROUND: If pixclock of specs->modedb[0] is not supported, the kernel stops.
// Therefore, we look here for the best mode (same size, highest supported pixclock)
fb_videomode_to_var(&fb_info->info->var, &specs->modedb[0]);
bestMode = (struct fb_videomode *)(fb_find_best_mode(&fb_info->info->var, &fb_info->info->modelist));
if(bestMode == NULL)
{
// Error, no matching mode found
return;
}
console_lock();
fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
dcmode.pclk = bestMode->pixclock;
dcmode.pclk = PICOS2KHZ(dcmode.pclk);
dcmode.pclk *= 1000;
printk(">>> DBG: pclk=%d\n",dcmode.pclk);
dcmode.h_ref_to_sync = 1;
dcmode.v_ref_to_sync = 1;
dcmode.h_sync_width = bestMode->hsync_len;
dcmode.v_sync_width = bestMode->vsync_len;
dcmode.h_back_porch = bestMode->left_margin;
dcmode.v_back_porch = bestMode->upper_margin;
dcmode.h_active = bestMode->xres;
dcmode.v_active = bestMode->yres;
dcmode.h_front_porch = bestMode->right_margin;
dcmode.v_front_porch = bestMode->lower_margin;
tegra_dc_set_fb_mode(fb_info->win.dc, specs->modedb, false);
fb_videomode_to_var(&fb_info->info->var, bestMode);
fb_notifier_call_chain(FB_EVENT_MODE_CHANGE_ALL, &event);
fb_notifier_call_chain(FB_EVENT_BLANK, &event);
console_unlock();
#else
fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
#endif
mutex_unlock(&fb_info->info->lock);
}
The implementation is not perfect though. We still need to connect via UART, set the video mode manually with xrandr, since the default (4096x2160 30.0) does not work. And then re-plug the HDMI to the monitor.
export DISPLAY=:0
xrandr --output HDMI-0 --mode 3840x2160 --rate 30.0
Hope this helps,
Regards Tobias