DRM: add drm support for g12a

PD#160546: DRM: add drm support for g12a
Verified on g12a

Change-Id: I5bfa4ad388e181af629e013a8d7c516ae5fc3fa4
Signed-off-by: Yalong Liu <yalong.liu@amlogic.com>
This commit is contained in:
Yalong Liu
2018-02-08 20:55:04 +08:00
committed by Yixun Lan
parent 8d8181d96e
commit ae37c44fc6
15 changed files with 1939 additions and 45 deletions

View File

@@ -14133,6 +14133,9 @@ AMLOGIC DRM DRIVER
M: Sky Zhou <sky.zhou@amlogic.com>
F: driver/amlogic/drm/*
F: driver/amlogic/drm/am_meson_fbdev.c
F: include/linux/amlogic/meson_drm.h
F: arch/arm64/boot/dts/amlogic/g12a_skt_buildroot.dts
F: arch/arm64/boot/dts/amlogic/mesong12a_drm.dtsi
AMLOGIC ADD S400EMMC DTS
M: Yue Gui <yuegui.he@amlogic.com>

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
/ {
dvalin@0xffe40000 {
gpu:dvalin@0xffe40000 {
compatible = "arm,malit60x", "arm,malit6xx", "arm,mali-midgard";
#cooling-cells = <2>; /* min followed by max */
reg = <0 0xFFE40000 0 0x04000>, /*mali APB bus base address*/

View File

@@ -0,0 +1,66 @@
/*
* arch/arm64/boot/dts/amlogic/meson_drm.dtsi
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
/ {
venc-cvbs {
status = "okay";
compatible = "amlogic,meson-gxbb-cvbs";
ports {
#address-cells = <1>;
#size-cells = <0>;
enc_cvbs_in: port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
venc_cvbs_in_vpu: endpoint@0 {
reg = <0>;
remote-endpoint = <&vpu_out_venc_cvbs>;
};
};
};
};
drm_vpu:drm@d0100000 {
status = "okay";
compatible = "amlogic,meson-gxbb";
reg = <0x0 0xd0100000 0x0 0x100000>,
<0x0 0xc883c000 0x0 0x1000>,
<0x0 0xc8838000 0x0 0x1000>;
reg-names = "base", "hhi", "dmc";
interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
dma-coherent;
ports {
#address-cells = <1>;
#size-cells = <0>;
vpu_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
vpu_out_venc_cvbs: endpoint@0 {
reg = <0>;
remote-endpoint = <&venc_cvbs_in_vpu>;
};
};
};
};
};

View File

@@ -139,8 +139,6 @@ static bool am_meson_crtc_mode_fixup(struct drm_crtc *crtc,
void am_meson_crtc_enable(struct drm_crtc *crtc)
{
enum vmode_e mode;
int ret = 0;
char *name;
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
@@ -152,19 +150,7 @@ void am_meson_crtc_enable(struct drm_crtc *crtc)
//DRM_INFO("meson_crtc_enable %s\n", adjusted_mode->name);
name = am_meson_crtc_get_voutmode(adjusted_mode);
mode = validate_vmode(name);
if (mode == VMODE_MAX) {
DRM_ERROR("no matched vout mode\n");
return;
}
vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode);
ret = set_current_vmode(mode);
if (ret)
DRM_ERROR("new mode %s set error\n", name);
else
DRM_INFO("new mode %s set ok\n", name);
vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &mode);
set_vout_mode(name);
}
void am_meson_crtc_disable(struct drm_crtc *crtc)

View File

@@ -43,20 +43,25 @@ static int am_meson_gem_alloc_ion_buff(
if (!meson_gem_obj)
return -EINVAL;
//TODO,check flags to set different ion heap type.
handle = ion_alloc(client, meson_gem_obj->base.size,
//check flags to set different ion heap type.
//if flags is set to 0, need to use ion dma buffer.
if (((flags & (BO_USE_SCANOUT | BO_USE_CURSOR)) != 0)
|| (flags == 0)) {
handle = ion_alloc(client, meson_gem_obj->base.size,
0, (1 << ION_HEAP_TYPE_DMA), 0);
if (IS_ERR(handle)) {
}
else {
handle = ion_alloc(client, meson_gem_obj->base.size,
0, (1 << ION_HEAP_TYPE_SYSTEM), 0);
if (IS_ERR(handle)) {
DRM_ERROR("am_meson_gem_alloc_ion_buff FAILED.\n");
return -ENOMEM;
}
bscatter = true;
}
if (IS_ERR(handle)) {
DRM_ERROR("%s: FAILED, flags:0x%x.\n",
__func__, flags);
return -ENOMEM;
}
meson_gem_obj->handle = handle;
meson_gem_obj->bscatter = bscatter;
DRM_DEBUG("%s: allocate handle (%p).\n",
@@ -313,6 +318,42 @@ unlock:
return ret;
}
int am_meson_gem_create_ioctl(
struct drm_device *dev,
void *data,
struct drm_file *file_priv)
{
struct am_meson_gem_object *meson_gem_obj;
struct meson_drm *drmdrv = dev->dev_private;
struct ion_client *client = (struct ion_client *)drmdrv->gem_client;
struct drm_meson_gem_create *args = data;
int ret = 0;
meson_gem_obj = am_meson_gem_object_create(
dev, args->flags, args->size, client);
if (IS_ERR(meson_gem_obj))
return PTR_ERR(meson_gem_obj);
/*
* allocate a id of idr table where the obj is registered
* and handle has the id what user can see.
*/
ret = drm_gem_handle_create(file_priv,
&meson_gem_obj->base, &args->handle);
/* drop reference from allocate - handle holds it now. */
drm_gem_object_unreference_unlocked(&meson_gem_obj->base);
if (ret) {
DRM_ERROR("%s: create dumb handle failed %d\n",
__func__, ret);
return ret;
}
DRM_DEBUG("%s: create dumb %p with gem handle (0x%x)\n",
__func__, meson_gem_obj, args->handle);
return 0;
}
int am_meson_gem_create(struct meson_drm *drmdrv)
{
drmdrv->gem_client = meson_ion_client_create(-1, "meson-gem");

View File

@@ -17,7 +17,8 @@
#ifndef __AM_MESON_GEM_H
#define __AM_MESON_GEM_H
#include <drm/drm_gem.h>
#include <drm/drm_gem.h>
#include <linux/amlogic/meson_drm.h>
#include <ion/ion_priv.h>
#include "meson_drv.h"
@@ -50,6 +51,11 @@ int am_meson_gem_dumb_destroy(
struct drm_device *dev,
uint32_t handle);
int am_meson_gem_create_ioctl(
struct drm_device *dev,
void *data,
struct drm_file *file_priv);
int am_meson_gem_dumb_map_offset(
struct drm_file *file_priv,
struct drm_device *dev,

View File

@@ -140,7 +140,7 @@ void am_osd_do_display(
meson_fb = container_of(fb, struct am_meson_fb, base);
phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp);
if (meson_fb->bufp->bscatter)
DRM_ERROR("ERROR:am_meson_plane meet a scatter framebuffe.\nr");
DRM_ERROR("ERROR:am_meson_plane meet a scatter framebuffer.\n");
#else
/* Update Canvas with buffer address */
gem = drm_fb_cma_get_gem_obj(fb, 0);

View File

@@ -90,20 +90,6 @@ static struct osd_device_data_s osd_gxbb = {
.dummy_data = 0x00808000,
};
static struct osd_device_data_s osd_gxtvbb = {
.cpu_id = __MESON_CPU_MAJOR_ID_GXTVBB,
.osd_ver = OSD_NORMAL,
.afbc_type = MESON_AFBC,
.osd_count = 2,
.has_deband = 0,
.has_lut = 0,
.has_rdma = 1,
.has_dolby_vision = 0,
.osd_fifo_len = 32,
.vpp_fifo_len = 0xfff,
.dummy_data = 0x0,
};
static struct osd_device_data_s osd_gxl = {
.cpu_id = __MESON_CPU_MAJOR_ID_GXL,
.osd_ver = OSD_NORMAL,
@@ -286,6 +272,13 @@ static irqreturn_t meson_irq(int irq, void *arg)
return IRQ_HANDLED;
}
#ifdef CONFIG_DRM_MESON_USE_ION
static const struct drm_ioctl_desc meson_ioctls[] = {
DRM_IOCTL_DEF_DRV(MESON_GEM_CREATE, am_meson_gem_create_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
};
#endif
static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -340,6 +333,8 @@ static struct drm_driver meson_driver = {
.dumb_map_offset = am_meson_gem_dumb_map_offset,
.gem_free_object_unlocked = am_meson_gem_object_free,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.ioctls = meson_ioctls,
.num_ioctls = ARRAY_SIZE(meson_ioctls),
#else
/* PRIME Ops */
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@ -614,10 +609,6 @@ static int meson_drv_probe(struct platform_device *pdev)
if (ret)
goto free_drm;
#ifdef CONFIG_DRM_MESON_BYPASS_MODE
osd_drm_debugfs_init();
#endif
return 0;
free_drm:

View File

@@ -693,6 +693,8 @@ void osd_drm_debugfs_add(
struct dentry *ent;
int i;
osd_drm_debugfs_init();
plane_osd_id[osd_id] = osd_id;
*plane_debugfs_dir = debugfs_create_dir(name, osd_debugfs_root);
if (!plane_debugfs_dir)
@@ -712,6 +714,8 @@ EXPORT_SYMBOL(osd_drm_debugfs_add);
void osd_drm_debugfs_init(void)
{
if (osd_debugfs_root)
return;
osd_debugfs_root = debugfs_create_dir("graphics", NULL);
if (!osd_debugfs_root)
pr_err("can't create debugfs dir\n");

View File

@@ -33,6 +33,11 @@ struct osd_plane_map_s {
u32 dst_w;
u32 dst_h;
int byte_stride;
u32 background_w;
u32 background_h;
u32 premult_en;
u32 afbc_en;
u32 afbc_inter_format;
u32 reserve;
};

View File

@@ -6257,6 +6257,35 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map)
plane_map->byte_stride,
plane_map->src_h,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
if (osd_hw.hwc_enable) {
#if 1
plane_map->zorder = 1;
plane_map->premult_en = 0;
plane_map->background_w = 1920;
plane_map->background_h = 1080;
plane_map->afbc_inter_format = 0x3;
plane_map->afbc_en = 0;
#endif
/* just get para, need update via do_hwc */
osd_hw.order[index] = plane_map->zorder;
osd_hw.premult_en[index] = plane_map->premult_en;
osd_hw.background_w = plane_map->background_w;
osd_hw.background_h = plane_map->background_h;
osd_hw.osd_afbcd[index].enable = plane_map->afbc_en;
osd_hw.osd_afbcd[index].inter_format =
plane_map->afbc_inter_format;
osd_hw.src_data[index].x = plane_map->src_x;
osd_hw.src_data[index].y = plane_map->src_y;
osd_hw.src_data[index].w = plane_map->src_w;
osd_hw.src_data[index].h = plane_map->src_h;
osd_hw.dst_data[index].x = plane_map->dst_x;
osd_hw.dst_data[index].y = plane_map->dst_y;
osd_hw.dst_data[index].w = plane_map->dst_w;
osd_hw.dst_data[index].h = plane_map->dst_h;
return 0;
}
width_dst = osd_hw.free_dst_data_backup[index].x_end -
osd_hw.free_dst_data_backup[index].x_start + 1;
@@ -6668,9 +6697,11 @@ void osd_page_flip(struct osd_plane_map_s *plane_map)
} else {
if (plane_map->phy_addr && plane_map->src_w
&& plane_map->src_h) {
#if 1
osd_hw.fb_gem[index].canvas_idx =
osd_extra_idx[index][ext_canvas_id];
ext_canvas_id ^= 1;
#endif
color = convert_panel_format(plane_map->format);
if (color) {
osd_hw.color_info[index] = color;

View File

@@ -186,7 +186,7 @@ char *get_vout_mode_uboot(void)
}
EXPORT_SYMBOL(get_vout_mode_uboot);
static int set_vout_mode(char *name)
int set_vout_mode(char *name)
{
enum vmode_e mode;
int ret = 0;

View File

@@ -119,4 +119,6 @@ extern void vdac_enable(bool on, unsigned int module_sel);
extern char *get_vout_mode_internal(void);
extern char *get_vout_mode_uboot(void);
extern int set_vout_mode(char *name);
#endif /* _VOUT_NOTIFY_H_ */

View File

@@ -0,0 +1,72 @@
/*
* include/uapi/drm/meson_drm.h
*
* Copyright (C) 2016 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _MESON_DRM_H
#define _MESON_DRM_H
#include <drm/drm.h>
/* memory type definitions. */
enum drm_meson_gem_mem_type {
/* Physically Continuous memory. */
MESON_BO_CONTIG = 1 << 0,
/* cachable mapping. */
MESON_BO_CACHABLE = 1 << 1,
/* write-combine mapping. */
MESON_BO_WC = 1 << 2,
MESON_BO_SECURE = 1 << 3,
MESON_BO_MASK = MESON_BO_CONTIG | MESON_BO_CACHABLE |
MESON_BO_WC
};
/* Use flags */
#define BO_USE_NONE 0
#define BO_USE_SCANOUT (1ull << 0)
#define BO_USE_CURSOR (1ull << 1)
#define BO_USE_CURSOR_64X64 BO_USE_CURSOR
#define BO_USE_RENDERING (1ull << 2)
#define BO_USE_LINEAR (1ull << 3)
#define BO_USE_SW_READ_NEVER (1ull << 4)
#define BO_USE_SW_READ_RARELY (1ull << 5)
#define BO_USE_SW_READ_OFTEN (1ull << 6)
#define BO_USE_SW_WRITE_NEVER (1ull << 7)
#define BO_USE_SW_WRITE_RARELY (1ull << 8)
#define BO_USE_SW_WRITE_OFTEN (1ull << 9)
#define BO_USE_EXTERNAL_DISP (1ull << 10)
#define BO_USE_PROTECTED (1ull << 11)
#define BO_USE_HW_VIDEO_ENCODER (1ull << 12)
#define BO_USE_CAMERA_WRITE (1ull << 13)
#define BO_USE_CAMERA_READ (1ull << 14)
#define BO_USE_RENDERSCRIPT (1ull << 16)
#define BO_USE_TEXTURE (1ull << 17)
/**
* User-desired buffer creation information structure.
*
* @size: user-desired memory allocation size.
* @flags: user request for setting memory type or cache attributes.
* @handle: returned a handle to created gem object.
* - this handle will be set by gem module of kernel side.
*/
struct drm_meson_gem_create {
uint64_t size;
uint32_t flags;
uint32_t handle;
};
#define DRM_MESON_GEM_CREATE 0x00
#define DRM_IOCTL_MESON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
DRM_MESON_GEM_CREATE, struct drm_meson_gem_create)
#endif /* _MESON_DRM_H */