User Tools

Site Tools


digic6:registers

DIGIC 6 Register Map:

Display layers and effects (HDMI, LCD, peaking/zebras control)

Digic 6 and 7 allow to define up to 8 hardware display layers. Each layer has independent data source, resolution, visible area and even can support either one of YUV variants or Indexed RGB input. Layers can also do some hardware effects like over/under exposure highlights (known as zebras) and probably more.

Note on directly writing the display registers

Depending on generation and model, Canon code will overwrite some (but not all) of the register values based on data structures stored in RAM. This applies also to layers code doesn't use.

Output has to be active when corresponding MMIO is being written, otherwise changes will be ignored.

Hardware compositor / layers

Please note that Digic 6 and up have two separate concepts of layers and image compositing. One is GPU accelerated software solution known as Ximr/XCM - used by Canon code to draw OSD (GUI).

For more details on Ximr/XCM and GUI, see this forum post: Compositors, layers, contexts in RGB and YUV - How Digic 7(6?)+ draw GUI

This section describes hardware layer / compositor supported on Digic 6 and 7 models. Canon uses it to mix OSD (GUI) with image preview (LiveView, playback, etc). Similar hardware exists in later models (Digic 8 and up) but it has different capabilities, thus it is covered in dedicated section: Digic 8 Registers

VRAM registration

Before VRAM buffer can be used by a hardware layer, it has to be registered and assigned an ID.

Base address Generation
0xD2030100 DIGIC 6
0xD2060040 DIGIC 7

MMIO structure is as below:

Offset Summary Description
+0x0 index Numerical ID, 8 bits - used for assignment in HW layer registers.
+0x4 pitch ? Derivative of image width. Computed as (( width \<\< 16) » 20) - 1 | 0x20000
+0x8 pointer-ish Vram address bit shifted 8 to the right. Possibly to enforce alignment.

MMIO has to be written in order, be aware of any compiler optimizations (best to set data structures as volatile).

Example code:

#define MMIO_D6_REGISTER_VRAM            0xD2030100
 
typedef struct mmio_d6_register_vram{
    volatile uint32_t index;
    volatile uint32_t pitch;
    volatile uint32_t ptr;
} mmio_d6_register_vram;
 
static void D6_register_VRAM(uint32_t buffer_index, uint32_t width, uint8_t* bmp_vram_indexed)
{
    mmio_d6_register_vram * vram_reg = (mmio_d6_register_vram*)MMIO_D6_REGISTER_VRAM;
 
    uint32_t old_int = cli();
    vram_reg->index = buffer_index;
    vram_reg->pitch = ((((width) << 0x10) >> 0x14) - 1) | 0x20000;
    vram_reg->ptr = (uint32_t)bmp_vram_indexed >> 8;
    sei(old_int);
}

Setting palette for Indexed RGB layers

This works differently than Digic 5 and below. There's a MMIO structure (per output), which takes a pointer to palette of 256 uint32_t entries stored in RAM. Palette is assigned to output, not layer - so all layers on given output will be rendered using the same palette.

Address didn't change between Digic 6 and 7.

Address Output
0xD2010680 HDMI
0xD20139A0 LCD
? Video

MMIO structure is as below:

Offset Summary Description
+0x0 apply Write 0x1 to apply selected palette
+0x4 flag maybe Unknown, Canon BL writes 0xFF
+0x8 pointer-ish Palette address, bit shifted 4 to the right. Possibly to enforce alignment.

Please note that fields have to be written in order: 'flag', 'pointer', 'apply'.

Example code:

typedef struct mmio_d6_palette{
    volatile uint32_t apply;
    volatile uint32_t flag;
    volatile uint32_t ptr;
} mmio_d6_palette;
 
static void D6_set_hw_palette(mmio_d6_palette* base_addr, uint32_t* palette)
{
    uint32_t old_int = cli();
    base_addr->flag = 0xff;
    base_addr->ptr = (uint32_t)palette >> 4;
    base_addr->apply = 1;
    sei(old_int);
}

Layers setup

There should be 3rd set of registers used for analog output similar to ones below. Address didn't change between Digic 6 and 7.

Base address Output
0xD2010510 HDMI
0xD2013810 LCD
?? Video

Each layer config consists of eight 32 bit configuration words (registers). There are 8 total layers (8 sets of 8 registers) starting from Base address. MMIO is Z ordered starting from bottom layer (0) to topmost one (7).

Offset Summary Description
+0 Flags Configures data type, transformations (flip, upscale), zebras, etc
+0x4 Vram index ? Assignment to a previously registered Vram buffer ID
+0x8 Input offsets Source buffer offsets (skips). x_off | (y_off << 16)
+0xC Vram resolution Source buffer size in pixels. width | (height << 16)
+0x10 Output offsets Destination offsets. x_off | (y_off << 16)
+0x14 scaling flag ? In HDMI mode it has to be set to 1 so vertical doubling works.
+0x18 ?
+0x1C ?

Vram index

Strangely enough, MMIO doesn't take source buffer address, but rather a number associated with VRAM, which is registered via different MMIO. See Vram registration.

Vram index register seems to also take two 16 bit values instead of one, possibly for layers that use separate image and alpha buffers (eg UYVY+AA, unconfirmed).

Resolution, offsets

  • Vram resolution is the resolution of entire buffer, in pixels.
  • Input offsets will “crop” source image by skipping everything up to X,Y (eg. to cut black borders)
  • Output offsets will move rendered image on screen by X,Y pixels.

Flags

So far we observed following flags by doing some empirical tests:

#define HWLAYER_ENABLE           0x1
#define HWLAYER_ALWAYS_SET     0x300 // At least on indexed, black (index 0?) becomes transparent with this not set
#define HWLAYER_FLIP_H        0x2000
#define HWLAYER_FLIP_V        0x4000
#define HWLAYER_DOUBLE_H     0x20000
#define HWLAYER_DOUBLE_V     0x40000
#define HWLAYER_ZEBRAS    0x10000000

// Going through lowest byte (except LSB which is ENABLE bit)
// reveals multiple combinations that work for some YUV and indexed formats.
#define HWLAYER_TYPE_UYVY_AA     0x40   // UYVY + separate alpha, eg. OSD
#define HWLAYER_TYPE_UYVY        0x04   // UYVY, no alpha - eg. LV
#define HWLAYER_TYPE_INDEXED_RGB 0x48   // Indexed RGB - eg. bootloader

// No idea, Canon uses HWLAYER_UNK on LCD, HWLAYER_ZEBRAS on HDMI
// Seems to have no effect, at least on indexed RGB
#define HWLAYER_UNK       0x40000000

Combining those flags is required to get desired effects. For example, 0x10000341 is YUV/no transparency buffer and zebras enabled on that layer. 0x660349 will result in indexed RGB source, upscaled 2x and mirrored in both axes.

Please note than for unknown reasons HWLAYER_DOUBLE_V doesn't work on HDMI unless scaling flag (+0x14) is set to 1.

Canon code will also forcefully overwrite some of the flags (zebras, upscaling register) from RAM data structures so values may need to be updated there instead of MMIO directly.

How does original firmware utilize HW layers?

In default configuration, bootloader uses Indexed RGB on layer 0 to draw things on screen. EOS codebase seems to use layer 0 to display active preview (LV, photo) image and layer 5 for GUI (referred as internally as OSD). Other layers are inactive.

The notes below are from 80D, but 77D (DIGIC 7) has the same setup:

Flags Kind Output Output type Output layer ID (80D)
0x40000305 OSD LCD YUV+Alpha. 5
0x10060305 OSD HDMI YUV+Alpha 5
0x40000341 LV LCD YUV 0
0x10000341 LV HDMI YUV 0
0x00000349 BootLdr LCD Indexed RGB 0
0x00000300 N/A Any Inactive Unused layers

Display effects (zebras, etc)

The table below documents registers used to configure underexposure / overexposure Zebra effects. Both can be enabled at the same time, settings for each output are separate. This means when camera outputs to multiple screens at the same time, each can have a different effect configuration.

There's likely 3rd set of registers for Video output.

Please note that to enable Zebras on layer/output you need to set a proper layer flag as described in Hardware compositor section.

Code suggests that they may be more hardware effects controlled by addresses just after those listed below.

Address Output Type Controls what?
0xD2010670 HDMI overexpo threshold and style
0xD2010674 HDMI overexpo color
0xD2010678 HDMI underexpo threshold and style
0xD201067c HDMI underexpo color
0xD2013970 LCD overexpo threshold and style
0xD2013974 LCD overexpo color
0xD2013978 LCD underexpo threshold and style
0xD201397C LCD underexpo color

Registers used by DispVram State object to control overexposure highlighting feature.

Zebra threshold / style register

**** **** **** **** **** **** **** ****
*... .... .... .... .... .... .... .... visibility (on/off)
.... .... *... .... .... .... .... .... stripes angle (45 / -45 deg)
.... .... .*.. .... .... .... .... .... stripes move speed (0-1)
.... .... ..** .... .... .... .... .... stripes style
.... .... .... .*** .... .... .... .... stripes opacity
.... .... .... .... **** **** .... .... threshold (underexpo)
.... .... .... .... .... .... **** **** threshold (overexpo)
Field Range Description
visibility 0,1 zebra visibility (do not confuse with Enable register)
angle 0-1 0: 45 deg, 1: -45 deg
speed 0-1 lines/dots are moving slower → faster
style 0-3 0: light dots, 1: thin lines, 2: thick lines, 3 = 0
opacity 0-7 0 for transparent → 7 for solid color
underexpo_th 0-255 Threshold on undexexpo register, ignored on overexpo
overexpo_th 0-255 Threshold on overexpo register, ignored on underexpo

Color register

Controls color of highlight overlays. ??YYUUVV format. Canon code defaults to black (00008080)

digic6/registers.txt · Last modified: 2025/05/06 10:12 by kitor