/** * amdgpu_dm_set_regamma_lut: Set regamma lut for the given CRTC. * @crtc: amdgpu_dm crtc state * * Update the underlying dc_stream_state's output transfer function (OTF) in * preparation for hardware commit. If no lut is specified by user, we default * to SRGB. * * RETURNS: * 0 on success, -ENOMEM if memory cannot be allocated to calculate the OTF. */ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) { struct drm_property_blob *blob = crtc->base.gamma_lut; struct dc_stream_state *stream = crtc->stream; struct drm_color_lut *lut; uint32_t lut_size; struct dc_gamma *gamma; enum dc_transfer_func_type old_type = stream->out_transfer_func->type; bool ret; if (!blob) { /* By default, use the SRGB predefined curve.*/ stream->out_transfer_func->type = TF_TYPE_PREDEFINED; stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; return 0; } lut = (struct drm_color_lut *)blob->data; lut_size = blob->length / sizeof(struct drm_color_lut); gamma = dc_create_gamma(); if (!gamma) return -ENOMEM; gamma->num_entries = lut_size; if (gamma->num_entries == MAX_COLOR_LEGACY_LUT_ENTRIES) gamma->type = GAMMA_RGB_256; else if (gamma->num_entries == MAX_COLOR_LUT_ENTRIES) gamma->type = GAMMA_CS_TFM_1D; else { /* Invalid lut size */ dc_gamma_release(&gamma); return -EINVAL; } /* Convert drm_lut into dc_gamma */ __drm_lut_to_dc_gamma(lut, gamma, gamma->type == GAMMA_RGB_256); /* Call color module to translate into something DC understands. Namely * a transfer function. */ stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; ret = mod_color_calculate_regamma_params(stream->out_transfer_func, gamma, true); dc_gamma_release(&gamma); if (!ret) { stream->out_transfer_func->type = old_type; DRM_ERROR("Out of memory when calculating regamma params\n"); return -ENOMEM; } return 0; }
/******************************************************************************* * Private functions ******************************************************************************/ static void construct(struct dc_context *ctx, struct dc_plane_state *plane_state) { plane_state->ctx = ctx; plane_state->gamma_correction = dc_create_gamma(); plane_state->gamma_correction->is_identity = true; plane_state->in_transfer_func = dc_create_transfer_func(); plane_state->in_transfer_func->type = TF_TYPE_BYPASS; plane_state->in_transfer_func->ctx = ctx; }