Friday, 8 June 2012

AMD Catalyst: Fixing Underscan

The proprietary ATI Catalyst fglrx driver always tends to underscan on my 1080p Panasonic TV.

Underscan is the condition of seeing a smaller image than should be the case: a "black border" around the edges. It is sometimes set by default to counteract overscan (where the image is enlarged and cropped; a throwback from the old days of CRT monitors).

The method for fixing it is non-obvious. One expects to be able to adjust the underscan/overscan settings via amdcccle - the AMD graphical configuration tool - but all too often amdcccle doesn't make this facility available for HDTVs.

Let me briefly step you through the bizarre history of AMD's support for fixing underscan, before presenting the solution that works for today's drivers. If you can see any logic behind AMD's strange decision-making, I'd be intrigued to hear about it!

The solution to this problem used to involve aticonfig's* --set-dispattrib command. You had to establish which arbitrary display name (from a possible list of of 12 candidates) the driver was using to identify the monitor in question, then identify the size/position settings for that display, and play around with them until the output looked right.

This used to be the procedure:

1) One would find the "display type" (here I'm outputting the horizontal offset in pixels for each display, so of the display types that return values, I can determine which display is the one I want, based on the horizontal offset):

$ for disptype in crt1 lvds tv cv tmds1 crt2 tmds2 tmds2i dfp3 dfp4 dfp5 dfp6 ; do amdconfig --query-dispattrib=${disptype},positionX; done

2) Then one would find the relevant settings for the display identified as exhibiting underscan:

$ for dispattrib in positionX positionY sizeX sizeY overscan ; do amdconfig --query-dispattrib=<display type>,${dispattrib} ; done

3) Finally, one would check over these values and amend them as appropriate:

$ sudo amdconfig --set-dispattrib=<display type>,<display attrib to correct>:<correct value>

However, here's the problem with this method: if you're using RandR >= 1.2 (which you will be if you're running recent software), this procedure will fail with the following.

$ amdconfig --query-monitor
Error: option --query-monitor is not supported when RandR 1.2 is enabled!

The next step was to work around this by disabling XRandR (by editing /etc/ati/amdpcsd and adding EnableRandR12=Sfalse under [AMDPCSROOT/SYSTEM/DDX], and by adding Option "EnableRandR12" "false" under the Driver section of your xorg.conf).

Again, this has been superseded.

The new solution, for cases where XRandR is >= 1.2, took me a while to figure out, and is surprisingly non-intuitive.

There is a practically undocumented variable in AMD's Persistent Configuration Store (PCS), used to store AMD specific driver settings. It's called DigitalHDTVDefaultUnderscan, and if set to false, it disables underscan completely.

Following this procedure should remove the black border and restore your 1:1 pixel mapping:

$ sudo amdconfig --set-pcs-val=MCIL,DigitalHDTVDefaultUnderscan,0
$ sudo reboot

One wonders what AMD was thinking, leaving such a common and important task out of amdcccle, and without documentation. It's a serious oversight.

As for other secret PCS variables: you can find some in /etc/ati/amdpcsdb, some in /etc/ati/amdpcsdb.default, and the rest are buried somewhere in the output of strings /usr/lib64/xorg/modules/drivers/fglrx_drv.so

Not exactly what one could call intuitive.

*Note that aticonfig is now called amdconfig.