So, here's the information about Radeon r300-r500 texture layouts. Note that pitch is in texels, and stride is in bytes.
Base offsets are 32-byte (256-bit) aligned. Pitch is at least 2 pixels.
Colorbuffers can be up to 4021x4021 pixels in 1/12 subpixel mode on r3xx/r4xx chips and 4096x4096 pixels on r5xx chips.
Base offsets are 4-byte (32-bit) aligned. Strides are always at least 32 bytes. For RS690, things are slightly different; strides are always at least 64 bytes.
Textures can be up to 2048x2048x2048 texels in size. On R500 chipsets, textures can be up to 4096x4096x4096 texels in size.
Additional levels are packed directly after the first level, largest to smallest.
Levels are always minified (reduced to the next smallest POT) in all dimensions as they get smaller.
Level base offsets are 32-byte aligned and are not adjustable (that is, the hardware computes them automatically on the fly, and there is no way to configure level base offsets).
Within each mip level, the images corresponding to the faces are stored in the order of the corresponding OpenGL #defines, i.e. in the order (+X, -X, +Y, -Y, +Z, -Z).
Images are stored consecutively, the only padding is for alignment. Alignment is as for all texture images (that is, 32 bytes).
Width vs. Pitch
Always use pitch instead of width for addressing. It's the only way to do rectangular and NPOT textures.
Width still needs to be set, of course.
Documenting this is a big TODO