AMDgpu Display Manager¶
The AMDgpu display manager,amdgpu_dm (or even simpler,dm) sits between DRM and DC. It acts as a liaison, converting DRMrequests into DC requests, and DC responses into DRM responses.
The root control structure isstructamdgpu_display_manager.
- structdm_compressor_info¶
Buffer info used by frame buffer compression
Definition:
struct dm_compressor_info { void *cpu_addr; struct amdgpu_bo *bo_ptr; uint64_t gpu_addr;};Members
cpu_addrMMIO cpu addr
bo_ptrPointer to the buffer object
gpu_addrMMIO gpu addr
- structdmub_hpd_work¶
Handle time consuming work in low priority outbox IRQ
Definition:
struct dmub_hpd_work { struct work_struct handle_hpd_work; struct dmub_notification *dmub_notify; struct amdgpu_device *adev;};Members
handle_hpd_workWork to be executed in a separate thread to handle hpd_low_irq
dmub_notifynotification for callback function
adevamdgpu_device pointer
- structvblank_control_work¶
Work data for vblank control
Definition:
struct vblank_control_work { struct work_struct work; struct amdgpu_display_manager *dm; struct amdgpu_crtc *acrtc; struct dc_stream_state *stream; bool enable;};Members
workKernel work data for the work event
dmamdgpu display manager device
acrtcamdgpu CRTC instance for which the event has occurred
streamDC stream for which the event has occurred
enabletrue if enabling vblank
- structidle_workqueue¶
Work data for periodic action in idle
Definition:
struct idle_workqueue { struct work_struct work; struct amdgpu_display_manager *dm; bool enable; bool running;};Members
workKernel work data for the work event
dmamdgpu display manager device
enabletrue if idle worker is enabled
runningtrue if idle worker is running
- structvupdate_offload_work¶
Work data for offloading task from vupdate handler
Definition:
struct vupdate_offload_work { struct work_struct work; struct amdgpu_device *adev; struct dc_stream_state *stream; struct dc_crtc_timing_adjust *adjust;};Members
workKernel work data for the work event
adevamdgpu_device back pointer
streamDC stream associated with the crtc
adjustDC CRTC timing adjust to be applied to the crtc
- structamdgpu_dm_luminance_data¶
Custom luminance data
Definition:
struct amdgpu_dm_luminance_data { u8 luminance; u8 input_signal;};Members
luminanceLuminance in percent
input_signalInput signal in range 0-255
- structamdgpu_dm_backlight_caps¶
Information about backlight
Definition:
struct amdgpu_dm_backlight_caps { union dpcd_sink_ext_caps *ext_caps; u32 aux_min_input_signal; u32 aux_max_input_signal; int min_input_signal; int max_input_signal; bool caps_valid; bool aux_support; u32 brightness_mask; u8 ac_level; u8 dc_level; u8 data_points; struct amdgpu_dm_luminance_data luminance_data[MAX_LUMINANCE_DATA_POINTS];};Members
ext_capsKeep the data
structwithall the information about thedisplay support for HDR.aux_min_input_signalMin brightness value supported by the display
aux_max_input_signalMax brightness value supported by the displayin nits.
min_input_signalminimum possible input in range 0-255.
max_input_signalmaximum possible input in range 0-255.
caps_validtrue if these values are from the ACPI interface.
aux_supportDescribes if the display supports AUX backlight.
brightness_maskAfter deriving brightness, OR it with this mask.Workaround for panels with issues with certain brightness values.
ac_levelthe default brightness if booted on AC
dc_levelthe default brightness if booted on DC
data_pointsthe number of custom luminance data points
luminance_datacustom luminance data
Description
Describe the backlight support for ACPI or eDP AUX.
- structdal_allocation¶
Tracks mapped FB memory for SMU communication
Definition:
struct dal_allocation { struct list_head list; struct amdgpu_bo *bo; void *cpu_ptr; u64 gpu_addr;};Members
listlist of dal allocations
boGPU buffer object
cpu_ptrCPU virtual address of the GPU buffer object
gpu_addrGPU virtual address of the GPU buffer object
- structhpd_rx_irq_offload_work_queue¶
Work queue to handle hpd_rx_irq offload work
Definition:
struct hpd_rx_irq_offload_work_queue { struct workqueue_struct *wq; spinlock_t offload_lock; bool is_handling_link_loss; bool is_handling_mst_msg_rdy_event; struct amdgpu_dm_connector *aconnector;};Members
wqworkqueue structure to queue offload work.
offload_lockTo protect fields of offload work queue.
is_handling_link_lossUsed to prevent inserting link loss event whenwe’re handling link loss
is_handling_mst_msg_rdy_eventUsed to prevent inserting mst messageready event when we’re already handling mst message ready event
aconnectorThe aconnector that this work queue is attached to
- structhpd_rx_irq_offload_work¶
hpd_rx_irq offload work structure
Definition:
struct hpd_rx_irq_offload_work { struct work_struct work; union hpd_irq_data data; struct hpd_rx_irq_offload_work_queue *offload_wq; struct amdgpu_device *adev;};Members
workoffload work
datareference irq data which is used while handling offload work
offload_wqoffload work queue that this work is queued to
adevamdgpu_device pointer
- structamdgpu_display_manager¶
Central amdgpu display manager device
Definition:
struct amdgpu_display_manager { struct dc *dc; struct dmub_srv *dmub_srv; struct dmub_notification *dmub_notify; dmub_notify_interrupt_callback_t dmub_callback[AMDGPU_DMUB_NOTIFICATION_MAX]; bool dmub_thread_offload[AMDGPU_DMUB_NOTIFICATION_MAX]; struct dmub_srv_fb_info *dmub_fb_info; const struct firmware *dmub_fw; struct amdgpu_bo *dmub_bo; u64 dmub_bo_gpu_addr; void *dmub_bo_cpu_addr; uint32_t dmcub_fw_version; uint32_t fw_inst_size; struct cgs_device *cgs_device; struct amdgpu_device *adev; struct drm_device *ddev; u16 display_indexes_num; struct drm_private_obj atomic_obj; struct mutex dc_lock; struct mutex audio_lock; struct drm_audio_component *audio_component; bool audio_registered; struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER]; struct list_head irq_handler_list_high_tab[DAL_IRQ_SOURCES_NUMBER]; struct common_irq_params pflip_params[DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1]; struct common_irq_params vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1]; struct common_irq_params vline0_params[DC_IRQ_SOURCE_DC6_VLINE0 - DC_IRQ_SOURCE_DC1_VLINE0 + 1]; struct common_irq_params vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1]; struct common_irq_params dmub_trace_params[1]; struct common_irq_params dmub_outbox_params[1]; spinlock_t irq_handler_list_table_lock; struct backlight_device *backlight_dev[AMDGPU_DM_MAX_NUM_EDP]; const struct dc_link *backlight_link[AMDGPU_DM_MAX_NUM_EDP]; uint8_t num_of_edps; struct amdgpu_dm_backlight_caps backlight_caps[AMDGPU_DM_MAX_NUM_EDP]; struct mod_freesync *freesync_module; struct hdcp_workqueue *hdcp_workqueue; struct workqueue_struct *vblank_control_workqueue; struct idle_workqueue *idle_workqueue; struct drm_atomic_state *cached_state; struct dc_state *cached_dc_state; struct dm_compressor_info compressor; const struct firmware *fw_dmcu; uint32_t dmcu_fw_version; const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; uint32_t active_vblank_irq_count;#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY); struct secure_display_context secure_display_ctx;#endif; struct hpd_rx_irq_offload_work_queue *hpd_rx_offload_wq; struct amdgpu_encoder mst_encoders[AMDGPU_DM_MAX_CRTC]; bool force_timing_sync; bool disable_hpd_irq; bool dmcub_trace_event_en; struct list_head da_list; struct completion dmub_aux_transfer_done; struct workqueue_struct *delayed_hpd_wq; u32 brightness[AMDGPU_DM_MAX_NUM_EDP]; u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP]; bool aux_hpd_discon_quirk; bool edp0_on_dp1_quirk; struct mutex dpia_aux_lock; void *bb_from_dmub; struct amdgpu_i2c_adapter *oem_i2c; struct fused_io_sync { struct completion replied; char reply_data[0x40]; } fused_io[8];};Members
dcDisplay Core control structure
dmub_srvDMUB service, used for controlling the DMUB on hardwarethat supports it. The pointer to the dmub_srv will beNULL on hardware that does not support it.
dmub_notifyNotification from DMUB.
dmub_callbackCallback functions to handle notification from DMUB.
dmub_thread_offloadFlag to indicate if callback is offload.
dmub_fb_infoFramebuffer regions for the DMUB.
dmub_fwDMUB firmware, required on hardware that has DMUB support.
dmub_boBuffer object for the DMUB.
dmub_bo_gpu_addrGPU virtual address for the DMUB buffer object.
dmub_bo_cpu_addrCPU address for the DMUB buffer object.
dmcub_fw_versionDMCUB firmware version.
fw_inst_sizeSize of the firmware instruction buffer.
cgs_deviceThe Common Graphics Services device. It provides an interface foraccessing registers.
adevAMDGPU base driver structure
ddevDRM base driver structure
display_indexes_numMax number of display streams supported
atomic_objIn combination with
dm_atomic_stateit helps manageglobal atomic state that doesn’t map cleanly into existingdrm resources, likedc_context.dc_lockGuards access to DC functions that can issue register writesequences.
audio_lockGuards access to audio instance changes.
audio_componentUsed to notify ELD changes to sound driver.
audio_registeredTrue if the audio component has been registeredsuccessfully, false otherwise.
irq_handler_list_low_tabLow priority IRQ handler table.
It is a n*m table consisting of n IRQ sources, and m handlers per IRQsource. Low priority IRQ handlers are deferred to a workqueue to beprocessed. Hence, they can sleep.
Note that handlers are called in the same order as they wereregistered (FIFO).
irq_handler_list_high_tabHigh priority IRQ handler table.
It is a n*m table, same as
irq_handler_list_low_tab. However,handlers in this table are not deferred and are called immediately.pflip_paramsPage flip IRQ parameters, passed to registered handlers whentriggered.
vblank_paramsVertical blanking IRQ parameters, passed to registered handlers whentriggered.
vline0_paramsOTG vertical interrupt0 IRQ parameters, passed to registeredhandlers when triggered.
vupdate_paramsVertical update IRQ parameters, passed to registered handlers whentriggered.
dmub_trace_paramsDMUB trace event IRQ parameters, passed to registered handlers whentriggered.
dmub_outbox_paramsDMUB Outbox parameters
irq_handler_list_table_lockSynchronizes access to IRQ tables
backlight_devBacklight control device
backlight_linkLink on which to control backlight
num_of_edpsnumber of backlight eDPs
backlight_capsCapabilities of the backlight device
freesync_moduleModule handling freesync calculations
hdcp_workqueueAMDGPU content protection queue
vblank_control_workqueueDeferred work for vblank control events.
idle_workqueuePeriodic work for idle events.
cached_stateCaches device atomic state for suspend/resume
cached_dc_stateCached state of content streams
compressorFrame buffer compression buffer. See
structdm_compressor_infofw_dmcuReference to DMCU firmware
dmcu_fw_versionVersion of the DMCU firmware
soc_bounding_boxgpu_info FW provided soc bounding box
structor0 if notavailable in FWactive_vblank_irq_countnumber of currently active vblank irqs
secure_display_ctxStore secure display relevant info. e.g. the ROI information, the work_struct to command dmub, etc.
hpd_rx_offload_wqWork queue to offload works of hpd_rx_irq
mst_encodersfake encoders used for DP MST.
force_timing_syncset via debugfs. When set, indicates that all connecteddisplays will be forced to synchronize.
disable_hpd_irqdisables all HPD and HPD RX interrupt handling in thedriver when true
dmcub_trace_event_enenable dmcub trace events
da_listDAL fb memory allocation list, for communication with SMU.
dmub_aux_transfer_donestructcompletionused to indicate when DMUBtransfers are donedelayed_hpd_wqwork queue used to delay DMUB HPD work
brightnesscached backlight values.
actual_brightnesslast successfully applied backlight values.
aux_hpd_discon_quirkquirk for hpd discon while aux is on-going.occurred on certain intel platform
edp0_on_dp1_quirkquirk for platforms that put edp0 on DP1.
dpia_aux_lockGuards access to DPIA AUX
bb_from_dmubBounding box data read from dmub during early initialization for DCN4+Data is stored as a byte array that should be casted to the appropriate bb struct
oem_i2cOEM i2c bus
fused_iodmub fused io interface
- structamdgpu_hdmi_vsdb_info¶
Keep track of the VSDB info
Definition:
struct amdgpu_hdmi_vsdb_info { unsigned int amd_vsdb_version; bool freesync_supported; unsigned int min_refresh_rate_hz; unsigned int max_refresh_rate_hz; bool replay_mode;};Members
amd_vsdb_versionVendor Specific Data Block Version, should beused to determine which Vendor Specific InfoFrame (VSIF) to send.
freesync_supportedFreeSync Supported.
min_refresh_rate_hzFreeSync Minimum Refresh Rate in Hz.
max_refresh_rate_hzFreeSync Maximum Refresh Rate in Hz
replay_modeReplay supported
Description
AMDGPU supports FreeSync over HDMI by using the VSDB section, and thisstructis useful to keep track of the display-specific information aboutFreeSync.
Lifecycle¶
DM (and consequently DC) is registered in the amdgpu base driver as a IPblock. When CONFIG_DRM_AMD_DC is enabled, the DM device IP block is added tothe base driver’s device list to be initialized and torn down accordingly.
The functions to do so are provided as hooks instructamd_ip_funcs.
- intdm_hw_init(structamdgpu_ip_block*ip_block)¶
Initialize DC device
Parameters
structamdgpu_ip_block*ip_blockPointer to the amdgpu_ip_block for this hw instance.
Description
Initialize thestructamdgpu_display_manager device. This involves callingthe initializers of each DM component, then populating thestructwith them.
Although the function implies hardware initialization, both hardware andsoftware are initialized here. Splitting them out to their relevant inithooks is a future TODO item.
Some notable things that are initialized here:
Display Core, both software and hardware
DC modules that we need (freesync and color management)
DRM software states
Interrupt sources and handlers
Vblank support
Debug FS entries, if enabled
- intdm_hw_fini(structamdgpu_ip_block*ip_block)¶
Teardown DC device
Parameters
structamdgpu_ip_block*ip_blockPointer to the amdgpu_ip_block for this hw instance.
Description
Teardown components withinstructamdgpu_display_manager that requirecleanup. This involves cleaning up the DRM device, DC, and any modules thatwere loaded. Also flush IRQ workqueues and disable them.
Interrupts¶
DM provides another layer of IRQ management on top of what the base driveralready provides. This is something that could be cleaned up, and is afuture TODO item.
The base driver provides IRQ source registration with DRM, handlerregistration into the base driver’s IRQ table, and a handler callbackamdgpu_irq_handler(), with which DRM calls on interrupts. This generichandler looks up the IRQ table, and calls the respectiveamdgpu_irq_src_funcs.process hookups.
What DM provides on top are two IRQ tables specifically for top-half andbottom-half IRQ handling, with the bottom-half implementing workqueues:
They override the base driver’s IRQ table, and the effect can be seenin the hooks that DM provides foramdgpu_irq_src_funcs.process. Theyare all set to the DM generic handleramdgpu_dm_irq_handler(), which looks upDM’s IRQ tables. However, in order for base driver to recognize this hook, DMstill needs to register the IRQ with the base driver. Seedce110_register_irq_handlers() anddcn10_register_irq_handlers().
To expose DC’s hardware interrupt toggle to the base driver, DM implementsamdgpu_irq_src_funcs.set hooks. Base driver calls it throughamdgpu_irq_update() to enable or disable the interrupt.
- structamdgpu_dm_irq_handler_data¶
Data for DM interrupt handlers.
Definition:
struct amdgpu_dm_irq_handler_data { struct list_head list; interrupt_handler handler; void *handler_arg; struct amdgpu_display_manager *dm; enum dc_irq_source irq_source; struct work_struct work;};Members
listLinked list entry referencing the next/previous handler
handlerHandler function
handler_argArgument passed to the handler when triggered
dmDM which this handler belongs to
irq_sourceDC interrupt source that this handler is registered for
workwork struct
- voiddm_irq_work_func(structwork_struct*work)¶
Handle an IRQ outside of the interrupt handler proper.
Parameters
structwork_struct*workwork struct
- voidunregister_all_irq_handlers(structamdgpu_device*adev)¶
Cleans up handlers from the DM IRQ table
Parameters
structamdgpu_device*adevThe base driver device containing the DM device
Description
Go through low and high context IRQ tables and deallocate handlers.
- void*amdgpu_dm_irq_register_interrupt(structamdgpu_device*adev,structdc_interrupt_params*int_params,void(*ih)(void*),void*handler_args)¶
Register a handler within DM.
Parameters
structamdgpu_device*adevThe base driver device containing the DM device.
structdc_interrupt_params*int_paramsInterrupt parameters containing the source, and handler context
void(*ih)(void*)Function pointer to the interrupt handler to register
void*handler_argsArguments passed to the handler when the interrupt occurs
Description
Register an interrupt handler for the given IRQ source, under the givencontext. The context can either be high or low. High context handlers areexecuted directly within ISR context, while low context is executed within aworkqueue, thereby allowing operations that sleep.
Registered handlers are called in a FIFO manner, i.e. the most recentlyregistered handler will be called first.
Return
Handler datastructamdgpu_dm_irq_handler_data containing the IRQsource, handler function, and args
- voidamdgpu_dm_irq_unregister_interrupt(structamdgpu_device*adev,enumdc_irq_sourceirq_source,void*ih)¶
Remove a handler from the DM IRQ table
Parameters
structamdgpu_device*adevThe base driver device containing the DM device
enumdc_irq_sourceirq_sourceIRQ source to remove the given handler from
void*ihFunction pointer to the interrupt handler to unregister
Description
Go through both low and high context IRQ tables, and find the given handlerfor the given irq source. If found, remove it. Otherwise, do nothing.
- intamdgpu_dm_irq_init(structamdgpu_device*adev)¶
Initialize DM IRQ management
Parameters
structamdgpu_device*adevThe base driver device containing the DM device
Description
Initialize DM’s high and low context IRQ tables.
The N by M table contains N IRQ sources, with Mstructamdgpu_dm_irq_handler_data hooked together in a linked list. Thelist_heads are initialized here. When an interrupt n is triggered, all mhandlers are called in sequence, FIFO according to registration order.
The low context table requires special steps to initialize, since handlerswill be deferred to a workqueue. Seestructirq_list_head.
- voidamdgpu_dm_irq_fini(structamdgpu_device*adev)¶
Tear down DM IRQ management
Parameters
structamdgpu_device*adevThe base driver device containing the DM device
Description
Flush all work within the low context IRQ table.
- intamdgpu_dm_irq_handler(structamdgpu_device*adev,structamdgpu_irq_src*source,structamdgpu_iv_entry*entry)¶
Generic DM IRQ handler
Parameters
structamdgpu_device*adevamdgpu base driver device containing the DM device
structamdgpu_irq_src*sourceUnused
structamdgpu_iv_entry*entryData about the triggered interrupt
Description
Calls all registered high irq work immediately, and schedules work for lowirq. The DM IRQ table is used to find the corresponding handlers.
- voidamdgpu_dm_hpd_init(structamdgpu_device*adev)¶
hpd setup callback.
Parameters
structamdgpu_device*adevamdgpu_device pointer
Description
Setup the hpd pins used by the card (evergreen+).Enable the pin, set the polarity, and enable the hpd interrupts.
- voidamdgpu_dm_hpd_fini(structamdgpu_device*adev)¶
hpd tear down callback.
Parameters
structamdgpu_device*adevamdgpu_device pointer
Description
Tear down the hpd pins used by the card (evergreen+).Disable the hpd interrupts.
- voiddm_pflip_high_irq(void*interrupt_params)¶
Handle pageflip interrupt
Parameters
void*interrupt_paramsignored
Description
Handles the pageflip interrupt by notifying all interested partiesthat the pageflip has been completed.
- voiddm_crtc_high_irq(void*interrupt_params)¶
Handles CRTC interrupt
Parameters
void*interrupt_paramsused for determining the CRTC instance
Description
Handles the CRTC/VSYNC interrupt by notfying DRM’s VBLANKevent handler.
Atomic Implementation¶
WIP
- voidamdgpu_dm_atomic_commit_tail(structdrm_atomic_state*state)¶
AMDgpu DM’s commit tail implementation.
Parameters
structdrm_atomic_state*stateThe atomic state to commit
Description
This will tell DC to commit the constructed DC state from atomic_check,programming the hardware. Any failures here implies a hardware failure, sinceatomic check should have filtered anything non-kosher.
- intamdgpu_dm_atomic_check(structdrm_device*dev,structdrm_atomic_state*state)¶
Atomic check implementation for AMDgpu DM.
Parameters
structdrm_device*devThe DRM device
structdrm_atomic_state*stateThe atomic state to commit
Description
Validate that the given atomic state is programmable by DC into hardware.This involves constructing astructdc_state reflecting the new hardwarestate we wish to commit, then querying DC to see if it is programmable. It’simportant not to modify the existing DC state. Otherwise, atomic_checkmay unexpectedly commit hardware changes.
When validating the DC state, it’s important that the right locks areacquired. For full updates case which removes/adds/updates streams on oneCRTC while flipping on another CRTC, acquiring global lock will guaranteethat any such full update commit will wait for completion of any outstandingflip using DRMs synchronization events.
Note that DM adds the affected connectors for all CRTCs in state, when thatmight not seem necessary. This is because DC stream creation requires theDC sink, which is tied to the DRM connector state. Cleaning this up shouldbe possible but non-trivial - a possible TODO item.
Return
-Error code if validation failed.
Color Management Properties¶
We have three types of color management in the AMD display driver.1. the legacydrm_crtc DEGAMMA, CTM, and GAMMA properties2. AMD driver private color management ondrm_plane anddrm_crtc3. AMD plane color pipeline
The CRTC properties are the original color management. When they wereimplemented per-plane color management was not a thing yet. Becauseof that we could get away with plumbing the DEGAMMA and CTMproperties to pre-blending HW functions. This is incompatible withper-plane color management, such as via the AMD private properties orthe new drm_plane color pipeline. The only compatible CRTC propertywith per-plane color management is the GAMMA property as it isapplied post-blending.
The AMD driver private color management properties are only exposedwhen the kernel is built explicitly with -DAMD_PRIVATE_COLOR. Theyare temporary building blocks on the path to full-fledgeddrm_planeanddrm_crtc color pipelines and lay the driver’s groundwork for thecolor pipelines.
The AMD plane color pipeline describes AMD’sdrm_colorops via thedrm_plane’s COLOR_PIPELINE property.
drm_crtc Properties¶
The DC interface to HW gives us the following color management blocksper pipe (surface):
Input gamma LUT (de-normalized)
Input CSC (normalized)
Surface degamma LUT (normalized)
Surface CSC (normalized)
Surface regamma LUT (normalized)
Output CSC (normalized)
But these aren’t a direct mapping to DRM color properties. Thecurrent DRM interface exposes CRTC degamma, CRTC CTM and CRTC regammawhile our hardware is essentially giving:
Plane CTM -> Plane degamma -> Plane CTM -> Plane regamma -> Plane CTM
The input gamma LUT block isn’t really applicable here since itoperates on the actual input data itself rather than the HW fprepresentation. The input and output CSC blocks are technicallyavailable to use as part of the DC interface but are typically usedinternally by DC for conversions between color spaces. These could beblended together with user adjustments in the future but for nowthese should remain untouched.
The pipe blending also happens after these blocks so we don’tactually support any CRTC props with correct blending with multipleplanes - but we can still support CRTC color management properties inDM in most single plane cases correctly with clever management of theDC interface in DM.
As per DRM documentation, blocks should be in hardware bypass whentheir respective property is set to NULL. A linear DGM/RGM LUT shouldalso considered as putting the respective block into bypass mode.
This means that the following configuration is assumed to be thedefault:
Plane DGM Bypass -> Plane CTM Bypass -> Plane RGM Bypass -> ... CRTCDGM Bypass -> CRTC CTM Bypass -> CRTC RGM Bypass
AMD Private Color Management on drm_plane¶
The AMD private color management properties on adrm_plane are:
AMD_PLANE_DEGAMMA_LUT
AMD_PLANE_DEGAMMA_LUT_SIZE
AMD_PLANE_DEGAMMA_TF
AMD_PLANE_HDR_MULT
AMD_PLANE_CTM
AMD_PLANE_SHAPER_LUT
AMD_PLANE_SHAPER_LUT_SIZE
AMD_PLANE_SHAPER_TF
AMD_PLANE_LUT3D
AMD_PLANE_LUT3D_SIZE
AMD_PLANE_BLEND_LUT
AMD_PLANE_BLEND_LUT_SIZE
AMD_PLANE_BLEND_TF
The AMD private color management property on adrm_crtc is:
AMD_CRTC_REGAMMA_TF
Use of these properties is discouraged.
AMD plane color pipeline¶
The AMDdrm_plane color pipeline is advertised for DCN generations3.0 and newer. It exposes these elements in this order:
1D curve colorop
Multiplier
3x4 CTM
1D curve colorop
1D LUT
3D LUT
1D curve colorop
1D LUT
The multiplier (#2) is a simple multiplier that is applied to allchannels.
The 3x4 CTM (#3) is a simple 3x4 matrix.
#1, and #7 are non-linear to linear curves. #4 is a linear tonon-linear curve. They support sRGB, PQ, and BT.709/BT.2020 EOTFs ortheir inverse.
The 1D LUTs (#5 and #8) are plain 4096 entry LUTs.
The 3DLUT (#6) is a tetrahedrally interpolated 17 cube LUT.
- voidamdgpu_dm_init_color_mod(void)¶
Initialize the color module.
Parameters
voidno arguments
Description
We’re not using the full color module, only certain components.Only call setup functions for components that we need.
- conststructdrm_color_lut*__extract_blob_lut(conststructdrm_property_blob*blob,uint32_t*size)¶
Extracts the DRM lut and lut size from a blob.
Parameters
conststructdrm_property_blob*blobDRM color mgmt property blob
uint32_t*sizelut size
Return
DRM LUT or NULL
- conststructdrm_color_lut32*__extract_blob_lut32(conststructdrm_property_blob*blob,uint32_t*size)¶
Extracts the DRM lut and lut size from a blob.
Parameters
conststructdrm_property_blob*blobDRM color mgmt property blob
uint32_t*sizelut size
Return
DRM LUT or NULL
- bool__is_lut_linear(conststructdrm_color_lut*lut,uint32_tsize)¶
check if the given lut is a linear mapping of values
Parameters
conststructdrm_color_lut*lutgiven lut to check values
uint32_tsizelut size
Description
It is considered linear if the lut represents:f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0,MAX_COLOR_LUT_ENTRIES)
Return
True if the given lut is a linear mapping of values, i.e. it acts like abypass LUT. Otherwise, false.
- void__drm_lut_to_dc_gamma(conststructdrm_color_lut*lut,structdc_gamma*gamma,boolis_legacy)¶
convert the drm_color_lut to dc_gamma.
Parameters
conststructdrm_color_lut*lutDRM lookup table for color conversion
structdc_gamma*gammaDC gamma to set entries
boolis_legacylegacy or atomic gamma
Description
The conversion depends on the size of the lut - whether or not it’s legacy.
- void__drm_lut32_to_dc_gamma(conststructdrm_color_lut32*lut,structdc_gamma*gamma)¶
convert the drm_color_lut to dc_gamma.
Parameters
conststructdrm_color_lut32*lutDRM lookup table for color conversion
structdc_gamma*gammaDC gamma to set entries
Description
The conversion depends on the size of the lut - whether or not it’s legacy.
- void__drm_ctm_to_dc_matrix(conststructdrm_color_ctm*ctm,structfixed31_32*matrix)¶
converts a DRM CTM to a DC CSC float matrix
Parameters
conststructdrm_color_ctm*ctmDRM color transformation matrix
structfixed31_32*matrixDC CSC float matrix
Description
The matrix needs to be a 3x4 (12 entry) matrix.
- void__drm_ctm_3x4_to_dc_matrix(conststructdrm_color_ctm_3x4*ctm,structfixed31_32*matrix)¶
converts a DRM CTM 3x4 to a DC CSC float matrix
Parameters
conststructdrm_color_ctm_3x4*ctmDRM color transformation matrix with 3x4 dimensions
structfixed31_32*matrixDC CSC float matrix
Description
The matrix needs to be a 3x4 (12 entry) matrix.
- int__set_legacy_tf(structdc_transfer_func*func,conststructdrm_color_lut*lut,uint32_tlut_size,boolhas_rom)¶
Calculates the legacy transfer function
Parameters
structdc_transfer_func*functransfer function
conststructdrm_color_lut*lutlookup table that defines the color space
uint32_tlut_sizesize of respective lut
boolhas_romif ROM can be used for hardcoded curve
Description
Only for sRGB input space
Return
0 in case of success, -ENOMEM if fails
- int__set_output_tf(structdc_transfer_func*func,conststructdrm_color_lut*lut,uint32_tlut_size,boolhas_rom)¶
calculates the output transfer function based on expected input space.
Parameters
structdc_transfer_func*functransfer function
conststructdrm_color_lut*lutlookup table that defines the color space
uint32_tlut_sizesize of respective lut
boolhas_romif ROM can be used for hardcoded curve
Return
0 in case of success. -ENOMEM if fails.
- int__set_output_tf_32(structdc_transfer_func*func,conststructdrm_color_lut32*lut,uint32_tlut_size,boolhas_rom)¶
calculates the output transfer function based on expected input space.
Parameters
structdc_transfer_func*functransfer function
conststructdrm_color_lut32*lutlookup table that defines the color space
uint32_tlut_sizesize of respective lut
boolhas_romif ROM can be used for hardcoded curve
Return
0 in case of success. -ENOMEM if fails.
- int__set_input_tf(structdc_color_caps*caps,structdc_transfer_func*func,conststructdrm_color_lut*lut,uint32_tlut_size)¶
calculates the input transfer function based on expected input space.
Parameters
structdc_color_caps*capsdc color capabilities
structdc_transfer_func*functransfer function
conststructdrm_color_lut*lutlookup table that defines the color space
uint32_tlut_sizesize of respective lut.
Return
0 in case of success. -ENOMEM if fails.
- int__set_input_tf_32(structdc_color_caps*caps,structdc_transfer_func*func,conststructdrm_color_lut32*lut,uint32_tlut_size)¶
calculates the input transfer function based on expected input space.
Parameters
structdc_color_caps*capsdc color capabilities
structdc_transfer_func*functransfer function
conststructdrm_color_lut32*lutlookup table that defines the color space
uint32_tlut_sizesize of respective lut.
Return
0 in case of success. -ENOMEM if fails.
- intamdgpu_dm_verify_lut3d_size(structamdgpu_device*adev,structdrm_plane_state*plane_state)¶
verifies if 3D LUT is supported and if user shaper and 3D LUTs match the hw supported size
Parameters
structamdgpu_device*adevamdgpu device
structdrm_plane_state*plane_statethe DRM plane state
Description
Verifies if pre-blending (DPP) 3D LUT is supported by the HW (DCN 2.0 ornewer) and if the user shaper and 3D LUTs match the supported size.
Return
0 on success. -EINVAL if lut size are invalid.
- intamdgpu_dm_verify_lut_sizes(conststructdrm_crtc_state*crtc_state)¶
verifies if DRM luts match the hw supported sizes
Parameters
conststructdrm_crtc_state*crtc_statethe DRM CRTC state
Description
Verifies that the Degamma and Gamma LUTs attached to thecrtc_stateare of the expected size.
Return
0 on success. -EINVAL if any lut sizes are invalid.
- intamdgpu_dm_check_crtc_color_mgmt(structdm_crtc_state*crtc,boolcheck_only)¶
Check if DRM color props are programmable by DC.
Parameters
structdm_crtc_state*crtcamdgpu_dm crtc state
boolcheck_onlyonly check color state without update dc stream
Description
This function just verifies CRTC LUT sizes, if there is enough space foroutput transfer function and if its parameters can be calculated by AMDcolor module. It also adjusts some settings for programming CRTC degamma atplane stage, using plane DGM block.
The RGM block is typically more fully featured and accurate acrossall ASICs - DCE can’t support a custom non-linear CRTC DGM.
For supporting both plane level color management and CRTC level colormanagement at once we have to either restrict the usage of some CRTCproperties or blend adjustments together.
Return
0 on success. Error code if validation fails.
- intamdgpu_dm_update_crtc_color_mgmt(structdm_crtc_state*crtc)¶
Maps DRM color management to DC stream.
Parameters
structdm_crtc_state*crtcamdgpu_dm crtc state
Description
With no plane level color management properties we’re free to use anyof the HW blocks as long as the CRTC CTM always comes before theCRTC RGM and after the CRTC DGM.
The CRTC RGM block will be placed in the RGM LUT block if it is non-linear.
The CRTC DGM block will be placed in the DGM LUT block if it is non-linear.
The CRTC CTM will be placed in the gamut remap block if it is non-linear.
The RGM block is typically more fully featured and accurate acrossall ASICs - DCE can’t support a custom non-linear CRTC DGM.
For supporting both plane level color management and CRTC level colormanagement at once we have to either restrict the usage of CRTC propertiesor blend adjustments together.
Return
0 on success. Error code if setup fails.
- intamdgpu_dm_update_plane_color_mgmt(structdm_crtc_state*crtc,structdrm_plane_state*plane_state,structdc_plane_state*dc_plane_state)¶
Maps DRM color management to DC plane.
Parameters
structdm_crtc_state*crtcamdgpu_dm crtc state
structdrm_plane_state*plane_stateDRM plane state
structdc_plane_state*dc_plane_statetarget DC surface
Description
Update the underlying dc_stream_state’s input transfer function (ITF) inpreparation for hardware commit. The transfer function used depends onthe preparation done on the stream for color management.
Return
0 on success. -ENOMEM if mem allocation fails.
DC Color Capabilities between DCN generations¶
DRM/KMS framework defines three CRTC color correction properties: degamma,color transformation matrix (CTM) and gamma, and two properties for degamma andgamma LUT sizes. AMD DC programs some of the color correction featurespre-blending but DRM/KMS has not per-plane color correction properties.
In general, the DRM CRTC color properties are programmed to DC, as follows:CRTC gamma after blending, and CRTC degamma pre-blending. Although CTM isprogrammed after blending, it is mapped to DPP hw blocks (pre-blending). Othercolor caps available in the hw is not currently exposed by DRM interface andare bypassed.
Color management caps (DPP and MPC)
Modules/color calculates various color operations which are translated toabstracted HW. DCE 5-12 had almost no important changes, but starting withDCN1, every new generation comes with fairly major differences in colorpipeline. Therefore, we abstract color pipe capabilities so modules/DM candecide mapping to HW block based on logical capabilities.
- MAX_SURFACES¶
MAX_SURFACES
representative of the upper bound of surfaces that can be piped to a single CRTC
- MAX_PLANES¶
MAX_PLANES
representative of the upper bound of planes that are supported by the HW
- structrom_curve_caps¶
predefined transfer function caps for degamma and regamma
Definition:
struct rom_curve_caps { uint16_t srgb : 1; uint16_t bt2020 : 1; uint16_t gamma2_2 : 1; uint16_t pq : 1; uint16_t hlg : 1;};Members
srgbRGB color space transfer func
bt2020BT.2020 transfer func
gamma2_2standard gamma
pqperceptual quantizer transfer function
hlghybrid log–gamma transfer function
- structdpp_color_caps¶
color pipeline capabilities for display pipe and plane blocks
Definition:
struct dpp_color_caps { uint16_t dcn_arch : 1; uint16_t input_lut_shared : 1; uint16_t icsc : 1; uint16_t dgam_ram : 1; uint16_t post_csc : 1; uint16_t gamma_corr : 1; uint16_t hw_3d_lut : 1; uint16_t ogam_ram : 1; uint16_t ocsc : 1; uint16_t dgam_rom_for_yuv : 1; struct rom_curve_caps dgam_rom_caps; struct rom_curve_caps ogam_rom_caps;};Members
dcn_archall DCE generations treated the same
input_lut_sharedshared with DGAM. Input LUT is different than most LUTs,just plain 256-entry lookup
icscinput color space conversion
dgam_ramprogrammable degamma LUT
post_cscpost color space conversion, before gamut remap
gamma_corrdegamma correction
hw_3d_lut3D LUT support. It implies a shaper LUT before. It may be sharedwith MPC by setting mpc:shared_3d_lut flag
ogam_ramprogrammable out/blend gamma LUT
ocscoutput color space conversion
dgam_rom_for_yuvpre-defined degamma LUT for YUV planes
dgam_rom_capspre-definied curve caps for degamma 1D LUT
ogam_rom_capspre-definied curve caps for regamma 1D LUT
Note
hdr_mult and gamut remap (CTM) are always available in DPP (in that order)
- structmpc_color_caps¶
color pipeline capabilities for multiple pipe and plane combined blocks
Definition:
struct mpc_color_caps { uint16_t gamut_remap : 1; uint16_t ogam_ram : 1; uint16_t ocsc : 1; uint16_t num_3dluts : 3; uint16_t num_rmcm_3dluts : 3; uint16_t shared_3d_lut:1; struct rom_curve_caps ogam_rom_caps; struct lut3d_caps mcm_3d_lut_caps; struct lut3d_caps rmcm_3d_lut_caps; bool preblend;};Members
gamut_remapcolor transformation matrix
ogam_ramprogrammable out gamma LUT
ocscoutput color space conversion matrix
num_3dlutsMPC 3D LUT; always assumes a preceding shaper LUT
num_rmcm_3dlutsnumber of RMCM 3D LUTS; always assumes a preceding shaper LUT
shared_3d_lutshared 3D LUT flag. Can be either DPP or MPC, but singleinstance
ogam_rom_capspre-definied curve caps for regamma 1D LUT
mcm_3d_lut_capsHW support cap for MCM LUT memory
rmcm_3d_lut_capsHW support cap for RMCM LUT memory
preblendwhether color manager supports preblend with MPC
- structdc_color_caps¶
color pipes capabilities for DPP and MPC hw blocks
Definition:
struct dc_color_caps { struct dpp_color_caps dpp; struct mpc_color_caps mpc;};Members
dppcolor pipes caps for DPP
mpccolor pipes caps for MPC
- enumpipe_split_policy¶
Pipe split strategy supported by DCN
Constants
MPC_SPLIT_DYNAMICDC will automatically decide how to split thepipe in order to bring the best trade-off between performance andpower consumption. This is the recommended option.
MPC_SPLIT_AVOIDAvoid pipe split, which means that DC will nottry any sort of split optimization.
MPC_SPLIT_AVOID_MULT_DISPWith this option, DC will only try tooptimize the pipe utilization when using a single display; if theuser connects to a second display, DC will avoid pipe split.
Description
Thisenumis used to define the pipe split policy supported by DCN. Bydefault, DC favors MPC_SPLIT_DYNAMIC.
- structdc_validation_set¶
Struct to store surface/stream associations for validation
Definition:
struct dc_validation_set { struct dc_stream_state *stream; struct dc_plane_state *plane_states[MAX_SURFACES]; uint8_t plane_count;};Members
streamStream state properties
plane_statesSurface state
plane_countTotal of active planes
- voiddc_get_underflow_debug_data_for_otg(structdc*dc,intprimary_otg_inst,structdc_underflow_debug_data*out_data)¶
Retrieve underflow debug data.
Parameters
structdc*dcPointer to the display core context.
intprimary_otg_instInstance index of the primary OTG that underflowed.
structdc_underflow_debug_data*out_dataPointer to a dc_underflow_debug_data
structtobe filled with debug information.
Description
This function collects and logs underflow-related HW states when underflow happens,including OTG underflow status, current read positions, frame count, and per-HUBP debug data.The results are stored in the provided out_data structure for further analysis or logging.
- booldc_capture_register_software_state(structdc*dc,structdc_register_software_state*state)¶
Capture software state for register programming
Parameters
structdc*dcDC context containing current display configuration
structdc_register_software_state*statePointer to dc_register_software_state structure to populate
Description
Extracts all software state variables that are used to program hardware registerfields across the display driver pipeline. This provides a complete snapshotof the software configuration that drives hardware register programming.
The function traverses the DC context and extracts values from:- Stream configurations (timing, format, DSC settings)- Plane states (surface format, rotation, scaling, cursor)- Pipe contexts (resource allocation, blending, viewport)- Clock manager (display clocks, DPP clocks, pixel clocks)- Resource context (DET buffer allocation, ODM configuration)
This is essential for underflow debugging as it captures the exact softwarestate that determines how registers are programmed, allowing analysis ofwhether underflow is caused by incorrect register programming or timing issues.
Return
true if state was successfully captured, false on error
- booldc_get_qos_info(structdc*dc,structdc_qos_info*info)¶
Retrieve Quality of Service (QoS) information from display core
Parameters
structdc*dcDC context containing current display configuration
structdc_qos_info*infoPointer to dc_qos_info structure to populate with QoS metrics
Description
This function retrieves QoS metrics from the display core that can be used bybenchmark tools to analyze display system performance. The function may takeseveral milliseconds to execute due to hardware measurement requirements.
QoS information includes:- Bandwidth bounds (lower limits in Mbps)- Latency bounds (upper limits in nanoseconds)- Hardware-measured bandwidth metrics (peak/average in Mbps)- Hardware-measured latency metrics (maximum/average in nanoseconds)
The function will populate the provided dc_qos_info structure with currentQoS measurements. If hardware measurement functions are not available forthe current DCN version, the function returns false with zero’d info structure.
Return
true if QoS information was successfully retrieved, false if measurementfunctions are unavailable or hardware measurements cannot be performed
The color pipeline has undergone major changes between DCN hardwaregenerations. What’s possible to do before and after blending depends onhardware capabilities, as illustrated below by the DCN 2.0 and DCN 3.0 familiesschemas.
DCN 2.0 family color caps and mapping
DCN 3.0 family color caps and mapping
Blend Mode Properties¶
Pixel blend mode is a DRM plane composition property ofdrm_plane used todescribes how pixels from a foreground plane (fg) are composited with thebackground plane (bg). Here, we present main concepts of DRM blend mode to helpto understand how this property is mapped to AMD DC interface. See more aboutthis DRM property and the alpha blending equations inDRM PlaneComposition Properties.
Basically, a blend mode sets the alpha blending equation for planecomposition that fits the mode in which the alpha channel affects the state ofpixel color values and, therefore, the resulted pixel color. Forexample, consider the following elements of the alpha blending equation:
fg.rgb: Each of the RGB component values from the foreground’s pixel.
fg.alpha: Alpha component value from the foreground’s pixel.
bg.rgb: Each of the RGB component values from the background.
plane_alpha: Plane alpha value set by theplane “alpha” property, seemore inDRM Plane Composition Properties.
in the basic alpha blending equation:
out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
the alpha channel value of each pixel in a plane is ignored and only the planealpha affects the resulted pixel color values.
DRM has three blend mode to define the blend formula in the plane composition:
None: Blend formula that ignores the pixel alpha.
Pre-multiplied: Blend formula that assumes the pixel color values in aplane was already pre-multiplied by its own alpha channel before storage.
Coverage: Blend formula that assumes the pixel color values were notpre-multiplied with the alpha channel values.
and pre-multiplied is the default pixel blend mode, that means, when no blendmode property is created or defined, DRM considers the plane’s pixels haspre-multiplied color values. On IGT GPU tools, the kms_plane_alpha_blend testprovides a set of subtests to verify plane alpha and blend mode properties.
The DRM blend mode and its elements are then mapped by AMDGPU display manager(DM) to program the blending configuration of the Multiple Pipe/Plane Combined(MPC), as follows:
- structmpcc_blnd_cfg¶
MPCC blending configuration
Definition:
struct mpcc_blnd_cfg { struct tg_color black_color; enum mpcc_alpha_blend_mode alpha_mode; bool pre_multiplied_alpha; int global_gain; int global_alpha; bool overlap_only; int bottom_gain_mode; int background_color_bpc; int top_gain; int bottom_inside_gain; int bottom_outside_gain;};Members
black_colorbackground color.
alpha_modealpha blend mode (MPCC_ALPHA_BLND_MODE).
pre_multiplied_alphaWhether pixel color values were pre-multiplied by the alpha channel(MPCC_ALPHA_MULTIPLIED_MODE).
global_gainUsed when blend mode considers both pixel alpha and plane.
global_alphaPlane alpha value.
overlap_onlyWhether overlapping of different planes is allowed.
bottom_gain_modeBlend mode for bottom gain setting.
background_color_bpcBackground color for bpc.
top_gainTop gain setting.
bottom_inside_gainBlend mode for bottom inside.
bottom_outside_gainBlend mode for bottom outside.
Therefore, the blending configuration for a single MPCC instance on the MPCtree is defined bympcc_blnd_cfg, wherepre_multiplied_alpha is the alpha pre-multiplied mode flag used tosetMPCC_ALPHA_MULTIPLIED_MODE. It controls whether alpha ismultiplied (true/false), being only true for DRM pre-multiplied blend mode.mpcc_alpha_blend_mode defines the alpha blend mode regarding pixelalpha and plane alpha values. It sets one of the three modes forMPCC_ALPHA_BLND_MODE, as described below.
- enummpcc_alpha_blend_mode¶
define the alpha blend mode regarding pixel alpha and plane alpha values
Constants
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHAper pixel alpha using DPPalpha value
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAINperpixel alpha using DPP alpha value multiplied by a global gain (planealpha)
MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHAglobal alpha value, ignorespixel alpha and consider only plane alpha
DM then maps the elements ofenummpcc_alpha_blend_mode to those in the DRMblend formula, as follows:
MPC pixel alpha matchesDRM fg.alpha as the alpha component valuefrom the plane’s pixel
MPC global alpha matchesDRM plane_alpha when the pixel alpha shouldbe ignored and, therefore, pixel values are not pre-multiplied
MPC global gain assumesMPC global alpha value when bothDRMfg.alpha andDRM plane_alpha participate in the blend equation
In short,fg.alpha is ignored by selectingMPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA. On the other hand, (plane_alpha *fg.alpha) component becomes available by selectingMPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN. And theMPCC_ALPHA_MULTIPLIED_MODE defines if the pixel color values arepre-multiplied by alpha or not.
Blend configuration flow¶
The alpha blending equation is configured from DRM to DC interface by thefollowing path:
When updating a
drm_plane_state, DM callsamdgpu_dm_plane_fill_blending_from_plane_state()that mapsdrm_plane_stateattributes todc_plane_infostructtobe handled in theOS-agnostic component (DC).On DC interface,
structmpcc_blnd_cfgprograms theMPCC blend configuration considering thedc_plane_infoinput from DPP.