blob: 8eaca738e2fd5795a18c84bcee9c27df489bdfe4 [file] [log] [blame]
// 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 device *vpu_dev, 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(vpu_dev->of_node,
"osd_ver", &pipeline->osd_version);
if (ret)
DRM_ERROR("osd_ver parser failed, need fix it!!\n");
ret = of_property_read_u32(vpu_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);
}