drivers/gpu/drm/amd/display/modules/color/color_gamma.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/modules/color/color_gamma.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/modules/color/color_gamma.c
Extension
.c
Size
56699 bytes
Lines
2009
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct dividers {
	struct fixed31_32 divider1;
	struct fixed31_32 divider2;
	struct fixed31_32 divider3;
};


static bool build_coefficients(struct gamma_coefficients *coefficients,
		enum dc_transfer_func_predefined type)
{

	uint32_t i = 0;
	uint32_t index = 0;
	bool ret = true;

	if (type == TRANSFER_FUNCTION_SRGB)
		index = 0;
	else if (type == TRANSFER_FUNCTION_BT709)
		index = 1;
	else if (type == TRANSFER_FUNCTION_GAMMA22)
		index = 2;
	else if (type == TRANSFER_FUNCTION_GAMMA24)
		index = 3;
	else if (type == TRANSFER_FUNCTION_GAMMA26)
		index = 4;
	else {
		ret = false;
		goto release;
	}

	do {
		coefficients->a0[i] = dc_fixpt_from_fraction(
			numerator01[index], 10000000);
		coefficients->a1[i] = dc_fixpt_from_fraction(
			numerator02[index], 1000);
		coefficients->a2[i] = dc_fixpt_from_fraction(
			numerator03[index], 1000);
		coefficients->a3[i] = dc_fixpt_from_fraction(
			numerator04[index], 1000);
		coefficients->user_gamma[i] = dc_fixpt_from_fraction(
			numerator05[index], 1000);

		++i;
	} while (i != ARRAY_SIZE(coefficients->a0));
release:
	return ret;
}

static struct fixed31_32 translate_from_linear_space(
		struct translate_from_linear_space_args *args)
{
	const struct fixed31_32 one = dc_fixpt_from_int(1);

	struct fixed31_32 scratch_1, scratch_2;
	struct calculate_buffer *cal_buffer = args->cal_buffer;

	if (dc_fixpt_le(one, args->arg))
		return one;

	if (dc_fixpt_le(args->arg, dc_fixpt_neg(args->a0))) {
		scratch_1 = dc_fixpt_add(one, args->a3);
		scratch_2 = dc_fixpt_pow(
				dc_fixpt_neg(args->arg),
				dc_fixpt_recip(args->gamma));
		scratch_1 = dc_fixpt_mul(scratch_1, scratch_2);
		scratch_1 = dc_fixpt_sub(args->a2, scratch_1);

		return scratch_1;
	} else if (dc_fixpt_le(args->a0, args->arg)) {
		if (cal_buffer->buffer_index == 0) {
			cal_buffer->gamma_of_2 = dc_fixpt_pow(dc_fixpt_from_int(2),
					dc_fixpt_recip(args->gamma));
		}
		scratch_1 = dc_fixpt_add(one, args->a3);
		/* In the first region (first 16 points) and in the
		 * region delimited by START/END we calculate with
		 * full precision to avoid error accumulation.
		 */
		if ((cal_buffer->buffer_index >= PRECISE_LUT_REGION_START &&
			cal_buffer->buffer_index <= PRECISE_LUT_REGION_END) ||
			(cal_buffer->buffer_index < 16))
			scratch_2 = dc_fixpt_pow(args->arg,
					dc_fixpt_recip(args->gamma));
		else
			scratch_2 = dc_fixpt_mul(cal_buffer->gamma_of_2,
					cal_buffer->buffer[cal_buffer->buffer_index%16]);

		if (cal_buffer->buffer_index != -1) {
			cal_buffer->buffer[cal_buffer->buffer_index%16] = scratch_2;
			cal_buffer->buffer_index++;

Annotation

Implementation Notes