if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) returnfalse;
/* Some pixel formats are supported without any modifier */ if (modifier == DRM_FORMAT_MOD_LINEAR) { /* *Howeverthesepixelformatsneedtobesupportedwith *modifiersonly
*/ return !malidp_hw_format_is_afbc_only(format);
}
if (!fourcc_mod_is_vendor(modifier, ARM)) {
DRM_DEBUG_KMS("Unknown modifier (not Arm)\n"); returnfalse;
}
if (modifier &
~DRM_FORMAT_MOD_ARM_AFBC(AFBC_MOD_VALID_BITS)) {
DRM_DEBUG_KMS("Unsupported modifiers\n"); returnfalse;
}
modifiers = malidp_format_modifiers;
/* SPLIT buffers must use SPARSE layout */ if (WARN_ON_ONCE((modifier & AFBC_SPLIT) && !(modifier & AFBC_SPARSE))) returnfalse;
/* CBR only applies to YUV formats, where YTR should be always 0 */ if (WARN_ON_ONCE((modifier & AFBC_CBR) && (modifier & AFBC_YTR))) returnfalse;
while (*modifiers != DRM_FORMAT_MOD_INVALID) { if (*modifiers == modifier) break;
modifiers++;
}
/* return false, if the modifier was not found */ if (*modifiers == DRM_FORMAT_MOD_INVALID) {
DRM_DEBUG_KMS("Unsupported modifier\n"); returnfalse;
}
info = drm_format_info(format);
if (info->num_planes != 1) {
DRM_DEBUG_KMS("AFBC buffers expect one plane\n"); returnfalse;
}
if (malidp_hw_format_is_linear_only(format) == true) {
DRM_DEBUG_KMS("Given format (0x%x) is supported is linear mode only\n",
format); returnfalse;
}
/* *RGBformatsneedtoprovideYTRmodifierandYUVformatsshouldnot *provideYTRmodifier.
*/ if (!(info->is_yuv) != !!(modifier & AFBC_FORMAT_MOD_YTR)) {
DRM_DEBUG_KMS("AFBC_FORMAT_MOD_YTR is %s for %s formats\n",
info->is_yuv ? "disallowed" : "mandatory",
info->is_yuv ? "YUV" : "RGB"); returnfalse;
}
if (modifier & AFBC_SPLIT) { if (!info->is_yuv) { if (info->cpp[0] <= 2) {
DRM_DEBUG_KMS("RGB formats <= 16bpp are not supported with SPLIT\n"); returnfalse;
}
}
if ((info->hsub != 1) || (info->vsub != 1)) { if (!(format == DRM_FORMAT_YUV420_10BIT &&
(map->features & MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT))) {
DRM_DEBUG_KMS("Formats which are sub-sampled should never be split\n"); returnfalse;
}
}
}
if (modifier & AFBC_CBR) { if ((info->hsub == 1) || (info->vsub == 1)) {
DRM_DEBUG_KMS("Formats which are not sub-sampled should not have CBR set\n"); returnfalse;
}
}
returntrue;
}
staticbool malidp_format_mod_supported_per_plane(struct drm_plane *plane,
u32 format, u64 modifier)
{ return malidp_format_mod_supported(plane->dev, format, modifier);
}
switch (format) { case DRM_FORMAT_ARGB2101010: case DRM_FORMAT_RGBA1010102: case DRM_FORMAT_BGRA1010102: case DRM_FORMAT_ARGB8888: case DRM_FORMAT_RGBA8888: case DRM_FORMAT_BGRA8888: case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XBGR8888: case DRM_FORMAT_RGBX8888: case DRM_FORMAT_BGRX8888: case DRM_FORMAT_RGB888: case DRM_FORMAT_RGBA5551: case DRM_FORMAT_RGB565: /* always supported */ returntrue;
case DRM_FORMAT_ABGR2101010: case DRM_FORMAT_ABGR8888: case DRM_FORMAT_ABGR1555: case DRM_FORMAT_BGR565: /* supported, but if AFBC then must be sparse mode */ return (!afbc) || (afbc && sparse);
case DRM_FORMAT_BGR888: /* supported, but not for AFBC */ return !afbc;
case DRM_FORMAT_YUYV: case DRM_FORMAT_UYVY: case DRM_FORMAT_NV12: case DRM_FORMAT_YUV420: /* not supported */ returnfalse;
/* get the page sizes supported by the MMU */
ms->mmu_prefetch_pgsize = malidp_get_pgsize_bitmap(mp);
ms->mmu_prefetch_mode =
malidp_mmu_prefetch_select_mode(ms, &ms->mmu_prefetch_pgsize);
}
ret = malidp_se_check_scaling(mp, new_plane_state); if (ret) return ret;
/* validate the rotation constraints for each layer */ if (new_plane_state->rotation != DRM_MODE_ROTATE_0) { if (mp->layer->rot == ROTATE_NONE) return -EINVAL; if ((mp->layer->rot == ROTATE_COMPRESSED) && !(fb->modifier)) return -EINVAL; /* *packedRGB888/BGR888can'tberotatedorflipped *unlesstheyarestoredinacompressedway
*/ if ((fb->format->format == DRM_FORMAT_RGB888 ||
fb->format->format == DRM_FORMAT_BGR888) && !(fb->modifier)) return -EINVAL;
}
/* SMART layer does not support AFBC */ if (mp->layer->id == DE_SMART && fb->modifier) {
DRM_ERROR("AFBC framebuffer not supported in SMART layer"); return -EINVAL;
}
ms->rotmem_size = 0; if (new_plane_state->rotation & MALIDP_ROTATED_MASK) { int val;
val = mp->hwdev->hw->rotmem_required(mp->hwdev, new_plane_state->crtc_w,
new_plane_state->crtc_h,
fb->format->format,
!!(fb->modifier)); if (val < 0) return val;
/* first clear the rotation bits */
val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL);
val &= ~LAYER_ROT_MASK;
/* setup the rotation and axis flip bits */ if (new_state->rotation & DRM_MODE_ROTATE_MASK)
val |= ilog2(plane->state->rotation & DRM_MODE_ROTATE_MASK) <<
LAYER_ROT_OFFSET; if (new_state->rotation & DRM_MODE_REFLECT_X)
val |= LAYER_H_FLIP; if (new_state->rotation & DRM_MODE_REFLECT_Y)
val |= LAYER_V_FLIP;
val &= ~(LAYER_COMP_MASK | LAYER_PMUL_ENABLE | LAYER_ALPHA(0xff));
if (new_state->alpha != DRM_BLEND_ALPHA_OPAQUE) {
val |= LAYER_COMP_PLANE;
} elseif (new_state->fb->format->has_alpha) { /* We only care about blend mode if the format has alpha */ switch (pixel_alpha) { case DRM_MODE_BLEND_PREMULTI:
val |= LAYER_COMP_PIXEL | LAYER_PMUL_ENABLE; break; case DRM_MODE_BLEND_COVERAGE:
val |= LAYER_COMP_PIXEL; break;
}
}
val |= LAYER_ALPHA(plane_alpha);
val &= ~LAYER_FLOWCFG(LAYER_FLOWCFG_MASK); if (new_state->crtc) { struct malidp_crtc_state *m =
to_malidp_crtc_state(new_state->crtc->state);
if (m->scaler_config.scale_enable &&
m->scaler_config.plane_src_id == mp->layer->id)
val |= LAYER_FLOWCFG(LAYER_FLOWCFG_SCALE_SE);
}
/* set the 'enable layer' bit */
val |= LAYER_ENABLE;
formats = kcalloc(map->n_pixel_formats, sizeof(*formats), GFP_KERNEL); if (!formats) {
ret = -ENOMEM; goto cleanup;
}
for (i = 0; i < map->n_layers; i++) {
u8 id = map->layers[i].id;
/* build the list of DRM supported formats based on the map */ for (n = 0, j = 0; j < map->n_pixel_formats; j++) { if ((map->pixel_formats[j].layer & id) == id)
formats[n++] = map->pixel_formats[j].format;
}
plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY :
DRM_PLANE_TYPE_OVERLAY;
/* *AllthelayersexceptsmartlayersupportsAFBCmodifiers.
*/
plane = drmm_universal_plane_alloc(drm, struct malidp_plane, base,
crtcs, &malidp_de_plane_funcs, formats, n,
(id == DE_SMART) ? linear_only_modifiers :
modifiers, plane_type, NULL); if (IS_ERR(plane)) {
ret = PTR_ERR(plane); goto cleanup;
}
/* Attach the YUV->RGB property only to video layers */ if (id & (DE_VIDEO1 | DE_VIDEO2)) { /* default encoding for YUV->RGB is BT601 NARROW */ enum drm_color_encoding enc = DRM_COLOR_YCBCR_BT601; enum drm_color_range range = DRM_COLOR_YCBCR_LIMITED_RANGE;
ret = drm_plane_create_color_properties(&plane->base,
BIT(DRM_COLOR_YCBCR_BT601) | \
BIT(DRM_COLOR_YCBCR_BT709) | \
BIT(DRM_COLOR_YCBCR_BT2020),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | \
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
enc, range); if (!ret) /* program the HW registers */
malidp_de_set_color_encoding(plane, enc, range); else
DRM_WARN("Failed to create video layer %d color properties\n", id);
}
}
kfree(formats);
return0;
cleanup:
kfree(formats);
return ret;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.