// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2025 Icenowy Zheng */ #include #include #include #include #include #include #include #include "vs_plane.h" int drm_format_to_vs_format(u32 drm_format, struct vs_format *vs_format) { switch (drm_format) { case DRM_FORMAT_XRGB4444: case DRM_FORMAT_RGBX4444: case DRM_FORMAT_XBGR4444: case DRM_FORMAT_BGRX4444: vs_format->color = VSDC_COLOR_FORMAT_X4R4G4B4; break; case DRM_FORMAT_ARGB4444: case DRM_FORMAT_RGBA4444: case DRM_FORMAT_ABGR4444: case DRM_FORMAT_BGRA4444: vs_format->color = VSDC_COLOR_FORMAT_A4R4G4B4; break; case DRM_FORMAT_XRGB1555: case DRM_FORMAT_RGBX5551: case DRM_FORMAT_XBGR1555: case DRM_FORMAT_BGRX5551: vs_format->color = VSDC_COLOR_FORMAT_X1R5G5B5; break; case DRM_FORMAT_ARGB1555: case DRM_FORMAT_RGBA5551: case DRM_FORMAT_ABGR1555: case DRM_FORMAT_BGRA5551: vs_format->color = VSDC_COLOR_FORMAT_A1R5G5B5; break; case DRM_FORMAT_RGB565: case DRM_FORMAT_BGR565: vs_format->color = VSDC_COLOR_FORMAT_R5G6B5; break; case DRM_FORMAT_XRGB8888: case DRM_FORMAT_RGBX8888: case DRM_FORMAT_XBGR8888: case DRM_FORMAT_BGRX8888: vs_format->color = VSDC_COLOR_FORMAT_X8R8G8B8; break; case DRM_FORMAT_ARGB8888: case DRM_FORMAT_RGBA8888: case DRM_FORMAT_ABGR8888: case DRM_FORMAT_BGRA8888: vs_format->color = VSDC_COLOR_FORMAT_A8R8G8B8; break; case DRM_FORMAT_ARGB2101010: case DRM_FORMAT_RGBA1010102: case DRM_FORMAT_ABGR2101010: case DRM_FORMAT_BGRA1010102: vs_format->color = VSDC_COLOR_FORMAT_A2R10G10B10; break; default: return -EINVAL; } switch (drm_format) { case DRM_FORMAT_RGBX4444: case DRM_FORMAT_RGBA4444: case DRM_FORMAT_RGBX5551: case DRM_FORMAT_RGBA5551: case DRM_FORMAT_RGBX8888: case DRM_FORMAT_RGBA8888: case DRM_FORMAT_RGBA1010102: vs_format->swizzle = VSDC_SWIZZLE_RGBA; break; case DRM_FORMAT_XBGR4444: case DRM_FORMAT_ABGR4444: case DRM_FORMAT_XBGR1555: case DRM_FORMAT_ABGR1555: case DRM_FORMAT_BGR565: case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: case DRM_FORMAT_ABGR2101010: vs_format->swizzle = VSDC_SWIZZLE_ABGR; break; case DRM_FORMAT_BGRX4444: case DRM_FORMAT_BGRA4444: case DRM_FORMAT_BGRX5551: case DRM_FORMAT_BGRA5551: case DRM_FORMAT_BGRX8888: case DRM_FORMAT_BGRA8888: case DRM_FORMAT_BGRA1010102: vs_format->swizzle = VSDC_SWIZZLE_BGRA; break; default: /* N/A for YUV formats */ vs_format->swizzle = VSDC_SWIZZLE_ARGB; } /* N/A for non-YUV formats */ vs_format->uv_swizzle = false; return 0; } dma_addr_t vs_fb_get_dma_addr(struct drm_framebuffer *fb, const struct drm_rect *src_rect) { struct drm_gem_dma_object *gem; dma_addr_t dma_addr; /* Get the physical address of the buffer in memory */ gem = drm_fb_dma_get_gem_obj(fb, 0); /* Compute the start of the displayed memory */ dma_addr = gem->dma_addr + fb->offsets[0]; /* Fixup framebuffer address for src coordinates */ dma_addr += drm_format_info_min_pitch(fb->format, 0, src_rect->x1 >> 16); dma_addr += (src_rect->y1 >> 16) * fb->pitches[0]; return dma_addr; } struct drm_plane_state *vs_plane_duplicate_state(struct drm_plane *plane) { struct vs_plane_state *vs_state, *vs_state_old; if (drm_WARN_ON(plane->dev, !plane->state)) return NULL; vs_state_old = to_vs_plane_state(plane->state); vs_state = kzalloc_obj(*vs_state, GFP_KERNEL); if (!vs_state) return NULL; __drm_atomic_helper_plane_duplicate_state(plane, &vs_state->base); memcpy(&vs_state->format, &vs_state_old->format, sizeof(struct vs_format)); return &vs_state->base; } void vs_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { __drm_atomic_helper_plane_destroy_state(state); kfree(state); } /* Called during init to allocate the plane's atomic state. */ void vs_plane_reset(struct drm_plane *plane) { struct vs_plane_state *vs_state; if (plane->state) { __drm_atomic_helper_plane_destroy_state(plane->state); kfree(plane->state); plane->state = NULL; } vs_state = kzalloc_obj(*vs_state, GFP_KERNEL); if (!vs_state) return; __drm_atomic_helper_plane_reset(plane, &vs_state->base); }