digic6:registers
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
digic6:registers [2022/02/21 22:52] – created kitor | digic6:registers [2025/05/05 19:14] (current) – kitor | ||
---|---|---|---|
Line 1: | Line 1: | ||
===== DIGIC 6 Register Map: ===== | ===== DIGIC 6 Register Map: ===== | ||
- | ==== LV peaking (Highlights | + | ===== Display layers and effects (HDMI, LCD, peaking/zebras control) ===== |
+ | |||
+ | Digic 6 and 7 allow to define up to 8 hardware display layers. Each of layers has independent source, resolution, visible area and even can support multiple variants of YUV and also Indexed RGB buffers. Layers can also do some hardware effects like over/under exposure highlights | ||
+ | |||
+ | === 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' | ||
+ | |||
+ | Output has to be active when MMIO is being written, otherwise changes will be ignored. | ||
+ | |||
+ | ==== Hardware compositor | ||
+ | |||
+ | There should be 3rd set of registers used for analog output similar to ones below. | ||
+ | |||
+ | ^ Base address | ||
+ | | '' | ||
+ | | '' | ||
+ | | ''??'' | ||
+ | |||
+ | Each address consists of **8** sets (layers), each consisting of eight 32 bit values representing each hardware layer. MMIO order starts from bottom layer (0) to topmost (7) in Z axis. | ||
+ | |||
+ | ^ Offset ^ Summary | ||
+ | | +0 | Flags | Configures data type, transformations (flip, upscale), zebras, etc | | ||
+ | | +0x4 | Vram index ? | Assignment to a previously registered Vram buffer ID | | ||
+ | | +0x8 | Input offsets | ||
+ | | +0xC | Vram resolution | ||
+ | | +0x10 | Output offsets | ||
+ | | +0x14 | scaling flag ? | In HDMI mode it has to be set to 1 so vertical doubling works. | | ||
+ | | +0x18 | ? | | | ||
+ | | +0x1C | ? | | | ||
+ | |||
+ | === Vram index === | ||
+ | |||
+ | Wildly enough, MMIO doesn' | ||
+ | |||
+ | 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 " | ||
+ | * 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 | ||
+ | #define HWLAYER_ALWAYS_SET | ||
+ | #define HWLAYER_FLIP_H | ||
+ | #define HWLAYER_FLIP_V | ||
+ | #define HWLAYER_DOUBLE_H | ||
+ | #define HWLAYER_DOUBLE_V | ||
+ | #define HWLAYER_ZEBRAS | ||
+ | |||
+ | // Going through lowest byte (except LSB which is ENABLE bit) | ||
+ | // reveals multiple combinations that work for some YUV and indexed formats. | ||
+ | #define HWLAYER_TYPE_OSD | ||
+ | #define HWLAYER_TYPE_LV | ||
+ | #define HWLAYER_TYPE_INDEXED 0x48 | ||
+ | |||
+ | // No idea, Canon uses HWLAYER_UNK on LCD, HWLAYER_ZEBRAS on HDMI | ||
+ | // Seems to have no effect at leat on indexed RGB | ||
+ | #define HWLAYER_UNK | ||
+ | </ | ||
+ | |||
+ | Combining those flags is required to get desired effects. For example, `0x10000341` is YUV/no transparency | ||
+ | |||
+ | Please note than for unknown reasons HWLAYER_DOUBLE_V doesn' | ||
+ | |||
+ | 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 utilizes HW layers? === | ||
+ | |||
+ | In default configuration, | ||
+ | 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) ^ | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | |||
+ | |||
+ | ==== 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) ==== | ||
+ | |||
+ | 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' | ||
+ | |||
+ | Please note that to enable Zebras on layer/ | ||
+ | |||
+ | Code suggests that they may be more hardware effects controlled by addresses just after those listed below. | ||
^ Address | ^ Address | ||
- | | '' | ||
| '' | | '' | ||
| '' | | '' | ||
| '' | | '' | ||
| '' | | '' | ||
- | | '' | + | | '' |
- | | '' | + | | '' |
- | | '' | + | | '' |
- | | '' | + | | '' |
- | | '' | + | |
Registers used by '' | Registers used by '' | ||
- | ===Note on directly writing the registers=== | + | ==== Zebra threshold / style register ==== |
- | + | ||
- | Some models overwrite register values with ones stored in memory. For example, 750D.110 does that for enable register, 200D.101 overwrites both enable and style regs, EOS R does that only for HDMI enable | + | |
- | + | ||
- | ===Enable register=== | + | |
- | + | ||
- | '' | + | |
- | + | ||
- | ===Threshold / style register=== | + | |
< | < | ||
Line 48: | Line 212: | ||
- | ===Color register=== | + | ==== Color register=== |
Controls color of highlight overlays. ''?? | Controls color of highlight overlays. ''?? | ||
+ | |||
+ |
digic6/registers.1645480367.txt.gz · Last modified: 2022/02/21 22:52 by kitor