drm: add rgba1010102 formats support [1/1]

PD#SWPL-106925

Problem:
no rgba1010102 formats support

Solution:
add rgba1010102 formats support

Verify:
ay301

Test:
DRM-OSD-44

Change-Id: Ie8132c653eff65a45b5e34b4fe43ab2dd90c0550
Signed-off-by: Ao Xu <ao.xu@amlogic.com>
This commit is contained in:
Ao Xu
2023-01-06 17:02:22 +08:00
committed by gerrit autosubmit
parent b1dc84744a
commit e8de618364
12 changed files with 241 additions and 118 deletions
@@ -57,11 +57,13 @@
ports = <&connectors_dev>;
fbdev_sizes = <1920 1080 1920 2160 32>;
osd_ver = /bits/ 8 <OSD_V7>;
osd_afbc_mask = <4>;
/* 0:def group 1:def group + 1010102 formats */
osd_formats_group = <1>;
/* OSD1&OSD2 with afbc, OSD3 has no afbc */
osd_afbc_mask = <3>;
vfm_mode = <1>; /** 0:drm mode 1:composer mode */
memory-region = <&logo_reserved>;
primary_plane_index = <0>; /* primary plane index for crtcs */
crtc_masks = <1 1 1>; /*for encoder: 0:hdmi 1:lcd 2:cvbs*/
crtc_masks = <0 1 1>; /*for encoder: 0:hdmi 1:lcd 2:cvbs*/
vpu_topology: vpu_topology {
vpu_blocks {
+1 -1
View File
@@ -24,7 +24,7 @@ endif
$(MESON_DRM_MODULE_NAME)-y += meson_drv.o meson_plane.o \
meson_atomic.o meson_sysfs.o\
meson_writeback.o meson_logo.o\
meson_async_atomic.o \
meson_async_atomic.o meson_of_parser.o \
meson_vpu_pipeline_traverse.o \
meson_crtc.o meson_vpu_pipeline.o \
meson_vpu_pipeline_private.o \
+1 -1
View File
@@ -209,7 +209,7 @@ int meson_cvbs_dev_bind(struct drm_device *drm,
connector = &am_drm_cvbs->base.connector;
/* Encoder */
encoder->possible_crtcs = priv->crtc_masks[ENCODER_CVBS];
encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_CVBS];
drm_encoder_helper_add(encoder, &am_cvbs_encoder_helper_funcs);
ret = drm_encoder_init(drm, encoder, &am_cvbs_encoder_funcs,
+1 -25
View File
@@ -184,8 +184,7 @@ static int am_meson_drm_bind(struct device *dev)
struct meson_drm *priv;
struct drm_device *drm;
struct platform_device *pdev = to_platform_device(dev);
u32 crtc_masks[ENCODER_MAX];
int i, vpu_dma_mask, ret = 0;
int ret = 0;
meson_driver.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_RENDER;
@@ -207,29 +206,6 @@ static int am_meson_drm_bind(struct device *dev)
priv->bound_data.connector_component_bind = meson_connector_dev_bind;
priv->bound_data.connector_component_unbind = meson_connector_dev_unbind;
priv->osd_occupied_index = -1;
/*initialize encoders crtc_masks, it will replaced by dts*/
for (i = 0; i < ENCODER_MAX; i++)
priv->crtc_masks[i] = 1;
ret = of_property_read_u32_array(dev->of_node, "crtc_masks",
crtc_masks, ENCODER_MAX);
if (ret) {
DRM_ERROR("crtc_masks get fail!\n");
} else {
for (i = 0; i < ENCODER_MAX; i++)
priv->crtc_masks[i] = crtc_masks[i];
}
vpu_dma_mask = 0;
ret = of_property_read_u32(dev->of_node, "vpu_dma_mask", &vpu_dma_mask);
if (!ret && vpu_dma_mask == 1) {
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (ret)
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
DRM_ERROR("drm set dma mask fail\n");
}
dev_set_drvdata(dev, priv);
+18 -5
View File
@@ -51,6 +51,20 @@ enum vpu_enc_type {
ENCODER_MAX
};
struct meson_of_conf {
/*for encoder: 0:hdmi 1:lcd 2:cvbs*/
u32 crtc_masks[ENCODER_MAX];
u32 vfm_mode;
u32 osd_afbc_mask;
u32 crtcmask_osd[MESON_MAX_OSD];
u32 crtcmask_video[MESON_MAX_VIDEO];
u32 osd_formats_group;
};
struct meson_drm {
struct device *dev;
@@ -79,12 +93,8 @@ struct meson_drm {
u32 num_planes;
struct am_osd_plane *osd_planes[MESON_MAX_OSD];
struct am_video_plane *video_planes[MESON_MAX_VIDEO];
u32 crtcmask_osd[MESON_MAX_OSD];
u32 crtcmask_video[MESON_MAX_VIDEO];
u32 osd_afbc_mask;
/*for encoder: 0:hdmi 1:lcd 2:cvbs*/
u32 crtc_masks[ENCODER_MAX];
struct meson_of_conf of_conf;
/*CONFIG_AMLOGIC_DRM_EMULATE_FBDEV*/
struct meson_drm_fbdev_config ui_config;
@@ -109,6 +119,9 @@ int meson_atomic_commit(struct drm_device *dev,
struct drm_atomic_state *state,
bool nonblock);
void meson_atomic_helper_commit_tail(struct drm_atomic_state *old_state);
/*meson of parse*/
void meson_of_init(struct drm_device *dev, struct meson_drm *priv);
/*******************************/
#ifdef CONFIG_DEBUG_FS
+1 -1
View File
@@ -1870,7 +1870,7 @@ int meson_hdmitx_dev_bind(struct drm_device *drm,
connector->interlace_allowed = 1;
/* Encoder */
encoder->possible_crtcs = priv->crtc_masks[ENCODER_HDMI];
encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_HDMI];
drm_encoder_helper_add(encoder, &meson_hdmitx_encoder_helper_funcs);
ret = drm_encoder_init(drm, encoder, &meson_hdmitx_encoder_funcs,
DRM_MODE_ENCODER_TMDS, "am_hdmi_encoder");
+1 -1
View File
@@ -329,7 +329,7 @@ int meson_panel_dev_bind(struct drm_device *drm,
}
/* Encoder */
encoder->possible_crtcs = priv->crtc_masks[ENCODER_LCD];
encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_LCD];
drm_encoder_helper_add(encoder, &meson_panel_encoder_helper_funcs);
ret = drm_encoder_init(drm, encoder, &meson_panel_encoder_funcs,
encoder_type, "am_lcd_encoder");
+135
View File
@@ -0,0 +1,135 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include "meson_drv.h"
#include "meson_vpu_pipeline.h"
static void meson_parse_crtc_masks(struct device_node *node, struct meson_of_conf *conf)
{
int i, ret;
u32 crtc_masks[ENCODER_MAX];
ret = 0;
/*initialize encoders crtc_masks, it will replaced by dts*/
for (i = 0; i < ENCODER_MAX; i++)
conf->crtc_masks[i] = 1;
ret = of_property_read_u32_array(node, "crtc_masks",
crtc_masks, ENCODER_MAX);
if (ret) {
DRM_DEBUG("crtc_masks get fail!\n");
} else {
for (i = 0; i < ENCODER_MAX; i++)
conf->crtc_masks[i] = crtc_masks[i];
}
}
static void meson_parse_dma_mask(struct device *dev)
{
int ret, vpu_dma_mask;
ret = 0;
vpu_dma_mask = 0;
ret = of_property_read_u32(dev->of_node, "vpu_dma_mask", &vpu_dma_mask);
if (!ret && vpu_dma_mask == 1) {
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (ret)
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret)
DRM_ERROR("drm set dma mask fail\n");
}
}
static void meson_video_parse_config(struct drm_device *dev, struct meson_of_conf *conf)
{
u32 mode_flag = 0;
int ret;
ret = of_property_read_u32(dev->dev->of_node,
"vfm_mode", &mode_flag);
if (ret)
DRM_DEBUG("%s parse vfm mode fail!\n", __func__);
conf->vfm_mode = mode_flag;
}
static void meson_osd_parse_config(struct drm_device *dev, struct meson_of_conf *conf)
{
u32 osd_afbc_mask = 0xff;
u32 osd_formats_group = 0;
int ret;
ret = of_property_read_u32(dev->dev->of_node,
"osd_afbc_mask", &osd_afbc_mask);
if (ret)
DRM_DEBUG("%s parse osd afbc mask fail!\n", __func__);
conf->osd_afbc_mask = osd_afbc_mask;
ret = of_property_read_u32(dev->dev->of_node,
"osd_formats_group", &osd_formats_group);
if (ret)
DRM_DEBUG("%s parse osd formats group fail!\n", __func__);
conf->osd_formats_group = osd_formats_group;
}
static void am_meson_vpu_get_plane_crtc_mask(struct meson_drm *priv,
char *name, u32 num, u32 *crtc_mask)
{
struct device_node *np = priv->dev->of_node;
int ret;
ret = of_property_read_u32_array(np, name,
crtc_mask, num);
if (ret) {
DRM_DEBUG("undefined %s!\n", name);
return;
}
}
void meson_of_init(struct drm_device *dev, struct meson_drm *priv)
{
int ret;
u32 osd_occupied_index;
struct meson_of_conf *conf = &priv->of_conf;
struct meson_vpu_pipeline *pipeline = priv->pipeline;
meson_parse_crtc_masks(dev->dev->of_node, conf);
meson_parse_dma_mask(dev->dev);
ret = of_property_read_u8(dev->dev->of_node,
"osd_ver", &pipeline->osd_version);
ret = of_property_read_u32(dev->dev->of_node,
"osd_occupied_index", &osd_occupied_index);
if (!ret)
priv->osd_occupied_index = osd_occupied_index;
am_meson_vpu_get_plane_crtc_mask(priv, "crtcmask_of_osd",
pipeline->num_osds, conf->crtcmask_osd);
am_meson_vpu_get_plane_crtc_mask(priv, "crtcmask_of_video",
pipeline->num_video, conf->crtcmask_video);
/* overwrite ctrc mask of video&osd, these should be defined in xxx.dts,
* it is mainly suitable to the board with different configurations for
* the same chip.
*/
am_meson_vpu_get_plane_crtc_mask(priv, "overwrite_crtcmask_of_osd",
pipeline->num_osds, conf->crtcmask_osd);
am_meson_vpu_get_plane_crtc_mask(priv, "overwrite_crtcmask_of_video",
pipeline->num_video, conf->crtcmask_video);
meson_osd_parse_config(dev, conf);
meson_video_parse_config(dev, conf);
}
+47 -45
View File
@@ -57,6 +57,23 @@ static const u32 supported_drm_formats[] = {
DRM_FORMAT_RGB565,
};
static const u32 supported_drm_formats_v2[] = {
DRM_FORMAT_RGBA1010102,
DRM_FORMAT_ARGB2101010,
DRM_FORMAT_ABGR2101010,
DRM_FORMAT_BGRA1010102,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGBX8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGBA8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_RGB565,
};
static u64 video_fbc_modifier[] = {
DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_BASIC, 0),
DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_BASIC,
@@ -514,32 +531,6 @@ static int meson_video_plane_get_fb_info(struct drm_plane *plane,
return 0;
}
static u32 meson_video_parse_config(struct drm_device *dev)
{
u32 mode_flag = 0;
int ret;
ret = of_property_read_u32(dev->dev->of_node,
"vfm_mode", &mode_flag);
if (ret)
DRM_INFO("%s parse vfm mode fail!\n", __func__);
return mode_flag;
}
static u32 meson_osd_parse_config(struct drm_device *dev)
{
u32 osd_afbc_mask = 0;
int ret;
ret = of_property_read_u32(dev->dev->of_node,
"osd_afbc_mask", &osd_afbc_mask);
if (ret)
DRM_INFO("%s parse osd afbc mask fail!\n", __func__);
return osd_afbc_mask;
}
static const char *am_meson_video_fence_get_driver_name(struct dma_fence *fence)
{
return "meson";
@@ -1411,7 +1402,7 @@ static void meson_plane_get_primary_plane(struct meson_drm *priv,
for (i = 0; i < MESON_MAX_CRTC; i++) {
for (j = 0; j < MESON_MAX_OSDS; j++) {
if (i == priv->crtcmask_osd[j] &&
if (i == priv->of_conf.crtcmask_osd[j] &&
priv->osd_occupied_index != j) {
first_plane = (first_plane != -1) ? first_plane : j;
@@ -1430,9 +1421,12 @@ static struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv,
int i, u32 crtc_mask, enum drm_plane_type type)
{
struct am_osd_plane *osd_plane;
struct meson_of_conf *conf;
struct drm_plane *plane;
u32 zpos, min_zpos, max_zpos, osd_index;
char plane_name[8];
const u32 *formats_group;
int num_formats;
const char *const_plane_name;
osd_plane = devm_kzalloc(priv->drm->dev, sizeof(*osd_plane),
@@ -1446,6 +1440,7 @@ static struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv,
osd_plane->drv = priv;
osd_plane->plane_index = i;
osd_plane->plane_type = OSD_PLANE;
conf = &priv->of_conf;
#ifdef CONFIG_AMLOGIC_MEDIA_FB
get_logo_osd_reverse(&osd_index, &logo.osd_reverse);
@@ -1478,22 +1473,30 @@ static struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv,
else
osd_plane->osd_occupied = false;
if (priv->osd_afbc_mask) {
if (conf->osd_formats_group) {
formats_group = supported_drm_formats_v2;
num_formats = ARRAY_SIZE(supported_drm_formats_v2);
} else {
formats_group = supported_drm_formats;
num_formats = ARRAY_SIZE(supported_drm_formats);
}
if (conf->osd_afbc_mask & BIT(i)) {
drm_universal_plane_init(priv->drm, plane, 1 << crtc_mask,
&am_osd_plane_funs,
formats_group,
num_formats,
afbc_modifier,
type, const_plane_name);
} else {
priv->drm->mode_config.allow_fb_modifiers = false;
drm_universal_plane_init(priv->drm, plane, 1 << crtc_mask,
&am_osd_plane_funs,
supported_drm_formats,
ARRAY_SIZE(supported_drm_formats),
formats_group,
num_formats,
NULL,
type, const_plane_name);
priv->drm->mode_config.allow_fb_modifiers = true;
} else {
drm_universal_plane_init(priv->drm, plane, 1 << crtc_mask,
&am_osd_plane_funs,
supported_drm_formats,
ARRAY_SIZE(supported_drm_formats),
afbc_modifier,
type, const_plane_name);
}
drm_plane_create_blend_mode_property(plane,
BIT(DRM_MODE_BLEND_PIXEL_NONE) |
@@ -1575,17 +1578,15 @@ int am_meson_plane_create(struct meson_drm *priv)
struct am_osd_plane *plane;
struct am_video_plane *video_plane;
struct meson_vpu_pipeline *pipeline = priv->pipeline;
struct meson_of_conf *conf = &priv->of_conf;
enum drm_plane_type type[MESON_MAX_OSD];
int i, osd_index, video_index;
u32 vfm_mode;
u32 osd_afbc_mask;
memset(priv->osd_planes, 0, sizeof(struct am_osd_plane *) * MESON_MAX_OSD);
memset(priv->video_planes, 0, sizeof(struct am_video_plane *) * MESON_MAX_VIDEO);
/*calculate primary plane*/
meson_plane_get_primary_plane(priv, type);
osd_afbc_mask = meson_osd_parse_config(priv->drm);
/*osd plane*/
for (i = 0; i < MESON_MAX_OSD; i++) {
@@ -1593,8 +1594,9 @@ int am_meson_plane_create(struct meson_drm *priv)
continue;
osd_index = pipeline->osds[i]->base.index;
priv->osd_afbc_mask = osd_afbc_mask >> i & 1;
plane = am_osd_plane_create(priv, osd_index, priv->crtcmask_osd[i], type[i]);
plane = am_osd_plane_create(priv, osd_index,
conf->crtcmask_osd[i],
type[i]);
if (!plane)
return -ENOMEM;
@@ -1605,16 +1607,16 @@ int am_meson_plane_create(struct meson_drm *priv)
priv->osd_planes[i] = plane;
priv->num_planes++;
}
vfm_mode = meson_video_parse_config(priv->drm);
/*video plane: init after osd to provide osd id at first.*/
for (i = 0; i < pipeline->num_video; i++) {
video_index = pipeline->video[i]->base.index;
video_plane = am_video_plane_create(priv, video_index, priv->crtcmask_video[i]);
video_plane = am_video_plane_create(priv, video_index,
conf->crtcmask_video[i]);
if (!video_plane)
return -ENOMEM;
video_plane->vfm_mode = vfm_mode;
video_plane->vfm_mode = conf->vfm_mode;
priv->video_planes[i] = video_plane;
priv->num_planes++;
}
+1 -33
View File
@@ -154,19 +154,7 @@ static void am_meson_vpu_power_config(bool en)
meson_vpu_power_config(VPU_VIU2_OSD_ROT, en);
}
static void am_meson_vpu_get_plane_crtc_mask(struct meson_drm *priv,
char *name, u32 num, u32 *crtc_mask)
{
struct device_node *np = priv->dev->of_node;
int ret;
ret = of_property_read_u32_array(np, name,
crtc_mask, num);
if (ret) {
DRM_DEBUG("undefined %s!\n", name);
return;
}
}
static int am_meson_vpu_bind(struct device *dev,
struct device *master, void *data)
@@ -178,7 +166,6 @@ static int am_meson_vpu_bind(struct device *dev,
struct meson_vpu_pipeline *pipeline = private->pipeline;
struct am_meson_crtc *amcrtc;
struct meson_vpu_data *vpu_data;
u32 osd_occupied_index;
int i, ret, irq;
DRM_DEBUG("%s in[%d]\n", __func__, __LINE__);
@@ -189,26 +176,7 @@ static int am_meson_vpu_bind(struct device *dev,
vpu_topology_populate(pipeline);
meson_vpu_block_state_init(private, private->pipeline);
ret = of_property_read_u8(dev->of_node,
"osd_ver", &pipeline->osd_version);
ret = of_property_read_u32(dev->of_node,
"osd_occupied_index", &osd_occupied_index);
if (!ret)
private->osd_occupied_index = osd_occupied_index;
am_meson_vpu_get_plane_crtc_mask(private, "crtcmask_of_osd",
pipeline->num_osds, private->crtcmask_osd);
am_meson_vpu_get_plane_crtc_mask(private, "crtcmask_of_video",
pipeline->num_video, private->crtcmask_video);
/* overwrite ctrc mask of video&osd, these should be defined in xxx.dts,
* it is mainly suitable to the board with different configurations for
* the same chip.
*/
am_meson_vpu_get_plane_crtc_mask(private, "overwrite_crtcmask_of_osd",
pipeline->num_osds, private->crtcmask_osd);
am_meson_vpu_get_plane_crtc_mask(private, "overwrite_crtcmask_of_video",
pipeline->num_video, private->crtcmask_video);
meson_of_init(drm_dev, private);
ret = am_meson_plane_create(private);
if (ret) {
+26 -3
View File
@@ -163,6 +163,22 @@ const struct meson_drm_format_info *__meson_drm_format_info(u32 format)
.hw_blkmode = BLOCK_MODE_32BIT,
.hw_colormat = COLOR_MATRIX_BGRA8888,
.alpha_replace = 0 },
{ .format = DRM_FORMAT_RGBA1010102,
.hw_blkmode = BLOCK_MODE_32BIT,
.hw_colormat = COLOR_MATRIX_RGBA1010102,
.alpha_replace = 0 },
{ .format = DRM_FORMAT_ARGB2101010,
.hw_blkmode = BLOCK_MODE_32BIT,
.hw_colormat = COLOR_MATRIX_ARGB2101010,
.alpha_replace = 0 },
{ .format = DRM_FORMAT_ABGR2101010,
.hw_blkmode = BLOCK_MODE_32BIT,
.hw_colormat = COLOR_MATRIX_ABGR2101010,
.alpha_replace = 0 },
{ .format = DRM_FORMAT_BGRA1010102,
.hw_blkmode = BLOCK_MODE_32BIT,
.hw_colormat = COLOR_MATRIX_BGRA1010102,
.alpha_replace = 0 },
{ .format = DRM_FORMAT_RGB888,
.hw_blkmode = BLOCK_MODE_24BIT,
.hw_colormat = COLOR_MATRIX_RGB888,
@@ -509,7 +525,7 @@ static void osd_afbc_config(struct meson_vpu_block *vblk,
static void osd_afbc_config_v7(struct meson_vpu_block *vblk,
struct rdma_reg_ops *reg_ops,
struct osd_mif_reg_s *reg,
u8 osd_index, bool afbc_en)
u8 osd_index, u32 pixel_format, bool afbc_en)
{
if (!afbc_en)
reg_ops->rdma_write_reg_bits(reg->viu_osd_ctrl_stat2, 0, 1, 1);
@@ -517,7 +533,14 @@ static void osd_afbc_config_v7(struct meson_vpu_block *vblk,
reg_ops->rdma_write_reg_bits(reg->viu_osd_ctrl_stat2, 1, 1, 1);
osd_mali_unpack_enable(vblk, reg_ops, reg, afbc_en);
osd_endian_mode(vblk, reg_ops, reg, !afbc_en);
if (pixel_format == DRM_FORMAT_RGBA1010102 ||
pixel_format == DRM_FORMAT_ARGB2101010 ||
pixel_format == DRM_FORMAT_ABGR2101010 ||
pixel_format == DRM_FORMAT_BGRA1010102)
osd_endian_mode(vblk, reg_ops, reg, afbc_en);
else
osd_endian_mode(vblk, reg_ops, reg, !afbc_en);
osd_mem_mode(vblk, reg_ops, reg, 1);
osd_mali_src_en_v7(vblk, reg_ops, reg, osd_index, afbc_en);
}
@@ -835,7 +858,7 @@ static void osd_set_state(struct meson_vpu_block *vblk,
osd_color_config(vblk, reg_ops, reg, pixel_format, mvos->pixel_blend, afbc_en);
if (pipeline->osd_version == OSD_V7)
osd_afbc_config_v7(vblk, reg_ops, reg, vblk->index, afbc_en);
osd_afbc_config_v7(vblk, reg_ops, reg, vblk->index, pixel_format, afbc_en);
else
osd_afbc_config(vblk, reg_ops, reg, vblk->index, afbc_en);
+4
View File
@@ -224,6 +224,10 @@ enum osd_color_matrix_e {
COLOR_MATRIX_ARGB8888,
COLOR_MATRIX_ABGR8888,
COLOR_MATRIX_BGRA8888,
COLOR_MATRIX_RGBA1010102 = 12,
COLOR_MATRIX_ARGB2101010,
COLOR_MATRIX_ABGR2101010,
COLOR_MATRIX_BGRA1010102,
/*for 24bit:blk-mode=BLOCK_MODE_24BIT*/
COLOR_MATRIX_RGB888 = 0,
COLOR_MATRIX_BGR888 = 5,