digic6:registers
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
digic6:registers [2025/05/05 19:09] – [Hardware compositor / layers] kitor | digic6:registers [2025/05/06 10:12] (current) – [Setting palette for Indexed RGB layers] kitor | ||
---|---|---|---|
Line 3: | Line 3: | ||
===== Display layers and effects (HDMI, LCD, peaking/ | ===== Display layers and effects (HDMI, LCD, peaking/ | ||
- | Digic 6 and 7 allow to define up to 8 hardware display layers. Each of layers | + | Digic 6 and 7 allow to define up to 8 hardware display layers. Each layer has independent |
=== Note on directly writing the display registers === | === Note on directly writing the display registers === | ||
Line 9: | Line 9: | ||
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' | 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' | ||
- | Output has to be active when MMIO is being written, otherwise changes will be ignored. | + | Output has to be active when corresponding |
==== Hardware compositor / layers ==== | ==== Hardware compositor / layers ==== | ||
- | There should be 3rd set of registers used for analog output similar to ones below. | + | 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: | ||
+ | [[https:// | ||
+ | |||
+ | 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, | ||
+ | |||
+ | ==== VRAM registration ==== | ||
+ | |||
+ | Before VRAM buffer can be used by a hardware layer, it has to be registered and assigned an ID. | ||
+ | |||
+ | |||
+ | ^ Base address | ||
+ | | '' | ||
+ | | '' | ||
+ | |||
+ | MMIO structure is as below: | ||
+ | |||
+ | ^ Offset ^ Summary | ||
+ | | +0x0 | index | Numerical ID, 8 bits - used for assignment in HW layer registers. | | ||
+ | | +0x4 | pitch ? | Derivative of image width. Computed as '' | ||
+ | | +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: | ||
+ | <code C> | ||
+ | #define MMIO_D6_REGISTER_VRAM | ||
+ | |||
+ | 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, | ||
+ | { | ||
+ | mmio_d6_register_vram * vram_reg = (mmio_d6_register_vram*)MMIO_D6_REGISTER_VRAM; | ||
+ | |||
+ | uint32_t old_int = cli(); | ||
+ | vram_reg-> | ||
+ | vram_reg-> | ||
+ | vram_reg-> | ||
+ | sei(old_int); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Setting palette for Indexed RGB layers ==== | ||
+ | |||
+ | This works differently than Digic 5 and below. There' | ||
+ | |||
+ | Address didn't change between Digic 6 and 7. | ||
+ | |||
+ | ^ Address | ||
+ | | '' | ||
+ | | '' | ||
+ | | ''?'' | ||
+ | |||
+ | MMIO structure is as below: | ||
+ | |||
+ | ^ Offset ^ Summary | ||
+ | | +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: ' | ||
+ | |||
+ | Example code: | ||
+ | <code C> | ||
+ | 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-> | ||
+ | base_addr-> | ||
+ | base_addr-> | ||
+ | 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 | ^ Base address | ||
Line 20: | Line 108: | ||
| ''??'' | | ''??'' | ||
- | Each address | + | Each layer config |
^ Offset ^ Summary | ^ Offset ^ Summary | ||
| +0 | Flags | Configures data type, transformations (flip, upscale), zebras, etc | | | +0 | Flags | Configures data type, transformations (flip, upscale), zebras, etc | | ||
- | | +0x4 | Vram index ? | Assignment to a peviously | + | | +0x4 | Vram index ? | Assignment to a previously |
- | | +0x8 | Input offsets | + | | +0x8 | Input offsets |
- | | +0xC | Vram resolution | + | | +0xC | Vram resolution |
- | | +0x10 | Output offsets | + | | +0x10 | Output offsets |
| +0x14 | scaling flag ? | In HDMI mode it has to be set to 1 so vertical doubling works. | | | +0x14 | scaling flag ? | In HDMI mode it has to be set to 1 so vertical doubling works. | | ||
| +0x18 | ? | | | | +0x18 | ? | | | ||
Line 34: | Line 123: | ||
=== Vram index === | === Vram index === | ||
- | Wildly | + | Strangely |
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). | 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). | ||
Line 59: | Line 148: | ||
// Going through lowest byte (except LSB which is ENABLE bit) | // Going through lowest byte (except LSB which is ENABLE bit) | ||
// reveals multiple combinations that work for some YUV and indexed formats. | // reveals multiple combinations that work for some YUV and indexed formats. | ||
- | # | + | # |
- | # | + | # |
- | # | + | # |
// No idea, Canon uses HWLAYER_UNK on LCD, HWLAYER_ZEBRAS on HDMI | // No idea, Canon uses HWLAYER_UNK on LCD, HWLAYER_ZEBRAS on HDMI | ||
- | // Seems to have no effect at leat on indexed RGB | + | // Seems to have no effect, at least on indexed RGB |
#define HWLAYER_UNK | #define HWLAYER_UNK | ||
</ | </ | ||
- | Combining those flags is required to get desired effects. For example, | + | Combining those flags is required to get desired effects. For example, |
- | Please note than for unknown reasons HWLAYER_DOUBLE_V doesn' | + | Please note than for unknown reasons |
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. | 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 original firmware | + | === How does original firmware |
In default configuration, | In default configuration, | ||
Line 90: | Line 179: | ||
| '' | | '' | ||
- | |||
- | ==== VRAM registration ==== | ||
- | |||
- | Before VRAM can be used by a hardware layer, it has to be registered and assigned an ID. | ||
- | |||
- | |||
- | ^ Base address | ||
- | | '' | ||
- | | '' | ||
- | |||
- | MMIO structure is as below: | ||
- | |||
- | ^ Offset ^ Summary | ||
- | | +0x0 | index | Numerical ID, 8 bits - used for assignment in HW layer registers. | ||
- | | +0x4 | pitch ? | Derivative of image width. Computed as '' | ||
- | | +0x8 | pointer-ish | Vram address bit shifted 8 to the right. Possibly to enforce alignment. | ||
- | |||
- | MMIO as to be written in order, be aware of any compiler optimizations (best to set data structures as volatile). | ||
- | |||
- | Example code: | ||
- | <code C> | ||
- | #define MMIO_D6_REGISTER_VRAM | ||
- | |||
- | 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, | ||
- | { | ||
- | mmio_d6_register_vram * vram_reg = (mmio_d6_register_vram*)MMIO_D6_REGISTER_VRAM; | ||
- | |||
- | uint32_t old_int = cli(); | ||
- | vram_reg-> | ||
- | vram_reg-> | ||
- | vram_reg-> | ||
- | sei(old_int); | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Setting palette for Indexed RGB layers ==== | ||
- | |||
- | This works differently than Digic 5 and below. There' | ||
- | |||
- | ^ Address | ||
- | | '' | ||
- | | '' | ||
- | | ''?'' | ||
- | |||
- | MMIO structure is as below: | ||
- | |||
- | ^ Offset ^ Summary | ||
- | | +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 has to be written in order: flag, pointer, apply. | ||
- | |||
- | Example code: | ||
- | <code C> | ||
- | 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-> | ||
- | base_addr-> | ||
- | base_addr-> | ||
- | sei(old_int); | ||
- | } | ||
- | </ | ||
==== Display effects (zebras, etc) ==== | ==== Display effects (zebras, etc) ==== | ||
Line 207: | Line 220: | ||
| speed | 0-1 | lines/dots are moving slower -> faster | | speed | 0-1 | lines/dots are moving slower -> faster | ||
| style | 0-3 | 0: light dots, 1: thin lines, 2: thick lines, 3 = 0 | | | style | 0-3 | 0: light dots, 1: thin lines, 2: thick lines, 3 = 0 | | ||
- | | opacity | + | | opacity |
| underexpo_th | 0-255 | Threshold on undexexpo register, ignored on overexpo | | underexpo_th | 0-255 | Threshold on undexexpo register, ignored on overexpo | ||
| overexpo_th | | overexpo_th |
digic6/registers.1746464996.txt.gz · Last modified: 2025/05/05 19:09 by kitor