Turns out the modes available can be edited in the kernel source, then compiled.
[JetPack Install Dir]/64_TX1/Linux_for_Tegra_64_tx1/sources/kernel_source/drivers/video/modedb.c contains the definitions of the modes used by the framebuffer and X11 in const struct fb_videomode cea_modes. In my specific example:
/* 97: 3840x2160p @ 60Hz */
{.refresh = 60, .xres = 3840, .yres = 2160, .pixclock = 1683,
.left_margin = 296, .right_margin = 176,
.upper_margin = 72, .lower_margin = 8,
.hsync_len = 88, .vsync_len = 10,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.flag = FB_FLAG_RATIO_16_9,
.vmode = FB_VMODE_NONINTERLACED},
This defines the 4K UHD @ 60fps mode. While modeline calculators and EDID editors alter the pixel clock in terms of MHz, the way they are defined in modedb.c is as a picosecond divisor. As seen above, the pixclock is set to 1683. 1000000/pixclock = the value in MHz for a modeline (e.g. 1683 → 1000000/1683 → 594.18).
The main problem is that this way of defining the pixel clock has a different granularity than the modelines and EDID definitions. While this is one is the closest match for the desired MHz, it creates a rounding error that leads to the 60.02Hz refresh rate (that then gets rejected by devices that have strict allowances).
So, the solution is:
- Use a tool that creates modes based off of the modedb.c pixclock format, rather than a "close enough" calculation based on a MHz format.
- Alter [JetPack Install Dir]/64_TX1/Linux_for_Tegra_64_tx1/sources/kernel_source/drivers/video/modedb.c -> const struct fb_videomode cea_modes to use the new mode.
- Compile the kernel.
- Either move the required files (zImage, Image, device tree binaries, modules) to the TX1 and restart, or to the JetPack locaions and flash the TX1.
- Configure X11 (/etc/X11/xorg.conf) to use the altered mode.