drivers/gpu/drm/arm/malidp_hw.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/arm/malidp_hw.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/arm/malidp_hw.c
Extension
.c
Size
46730 bytes
Lines
1393
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

switch (fmt) {
		case DRM_FORMAT_VUY101010:
			bpp = 30;
			break;
		case DRM_FORMAT_YUV420_10BIT:
			bpp = 15;
			break;
		case DRM_FORMAT_YUV420_8BIT:
			bpp = 12;
			break;
		default:
			bpp = 0;
		}
	}

	return bpp;
}

static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w,
				     u16 h, u32 fmt, bool has_modifier)
{
	/*
	 * Each layer needs enough rotation memory to fit 8 lines
	 * worth of pixel data. Required size is then:
	 *    size = rotated_width * (bpp / 8) * 8;
	 */
	int bpp = malidp_format_get_bpp(fmt);

	return w * bpp;
}

static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev,
					   u32 direction,
					   u16 addr,
					   u8 coeffs_id)
{
	int i;
	u16 scaling_control = MALIDP500_SE_CONTROL + MALIDP_SE_SCALING_CONTROL;

	malidp_hw_write(hwdev,
			direction | (addr & MALIDP_SE_COEFFTAB_ADDR_MASK),
			scaling_control + MALIDP_SE_COEFFTAB_ADDR);
	for (i = 0; i < ARRAY_SIZE(dp500_se_scaling_coeffs); ++i)
		malidp_hw_write(hwdev, MALIDP_SE_SET_COEFFTAB_DATA(
				dp500_se_scaling_coeffs[coeffs_id][i]),
				scaling_control + MALIDP_SE_COEFFTAB_DATA);
}

static int malidp500_se_set_scaling_coeffs(struct malidp_hw_device *hwdev,
					   struct malidp_se_config *se_config,
					   struct malidp_se_config *old_config)
{
	/* Get array indices into dp500_se_scaling_coeffs. */
	u8 h = (u8)se_config->hcoeff - 1;
	u8 v = (u8)se_config->vcoeff - 1;

	if (WARN_ON(h >= ARRAY_SIZE(dp500_se_scaling_coeffs) ||
		    v >= ARRAY_SIZE(dp500_se_scaling_coeffs)))
		return -EINVAL;

	if ((h == v) && (se_config->hcoeff != old_config->hcoeff ||
			 se_config->vcoeff != old_config->vcoeff)) {
		malidp500_se_write_pp_coefftab(hwdev,
					       (MALIDP_SE_V_COEFFTAB |
						MALIDP_SE_H_COEFFTAB),
					       0, v);
	} else {
		if (se_config->vcoeff != old_config->vcoeff)
			malidp500_se_write_pp_coefftab(hwdev,
						       MALIDP_SE_V_COEFFTAB,
						       0, v);
		if (se_config->hcoeff != old_config->hcoeff)
			malidp500_se_write_pp_coefftab(hwdev,
						       MALIDP_SE_H_COEFFTAB,
						       0, h);
	}

	return 0;
}

static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev,
				   struct malidp_se_config *se_config,
				   struct videomode *vm)
{
	unsigned long mclk;
	unsigned long pxlclk = vm->pixelclock; /* Hz */
	unsigned long htotal = vm->hactive + vm->hfront_porch +
			       vm->hback_porch + vm->hsync_len;
	unsigned long input_size = se_config->input_w * se_config->input_h;
	unsigned long a = 10;

Annotation

Implementation Notes