drm/rockchip: drv: add support kernel logo display

Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Change-Id: I30afec5114bbad9893a9fb9be4e1ba214a5fccad
This commit is contained in:
Sandy Huang
2021-08-10 14:43:22 +08:00
committed by Guochun Huang
parent 697bbdf85b
commit f0d2c7be96
7 changed files with 1152 additions and 32 deletions

View File

@@ -4,7 +4,8 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o \
rockchip_drm_gem.o rockchip_drm_logo.o \
rockchip_drm_vop.o rockchip_vop_reg.o \
rockchip_drm_vop2.o rockchip_vop2_reg.o
rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o

View File

@@ -32,6 +32,7 @@
#include "rockchip_drm_fb.h"
#include "rockchip_drm_fbdev.h"
#include "rockchip_drm_gem.h"
#include "rockchip_drm_logo.h"
#include "../drm_crtc_internal.h"
@@ -44,29 +45,6 @@
static bool is_support_iommu = true;
static struct drm_driver rockchip_drm_driver;
struct rockchip_drm_mode_set {
struct list_head head;
struct drm_framebuffer *fb;
struct drm_connector *connector;
struct drm_crtc *crtc;
struct drm_display_mode *mode;
int hdisplay;
int vdisplay;
int vrefresh;
int flags;
int picture_aspect_ratio;
int crtc_hsync_end;
int crtc_vsync_end;
int left_margin;
int right_margin;
int top_margin;
int bottom_margin;
bool mode_changed;
int ratio;
};
/**
* rockchip_drm_of_find_possible_crtcs - find the possible CRTCs for an active
* encoder port
@@ -624,10 +602,6 @@ static int rockchip_drm_bind(struct device *dev)
*/
drm_dev->irq_enabled = true;
ret = rockchip_drm_fbdev_init(drm_dev);
if (ret)
goto err_unbind_all;
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm_dev);
@@ -636,6 +610,12 @@ static int rockchip_drm_bind(struct device *dev)
if (ret)
DRM_DEBUG_KMS("No reserved memory region assign to drm\n");
rockchip_drm_show_logo(drm_dev);
ret = rockchip_drm_fbdev_init(drm_dev);
if (ret)
goto err_unbind_all;
drm_dev->mode_config.allow_fb_modifiers = true;
ret = drm_dev_register(drm_dev, 0);

View File

@@ -16,6 +16,8 @@
#include <linux/module.h>
#include <linux/component.h>
#include "../panel/panel-simple.h"
#define ROCKCHIP_MAX_FB_BUFFER 3
#define ROCKCHIP_MAX_CONNECTOR 2
#define ROCKCHIP_MAX_CRTC 4
@@ -44,6 +46,7 @@ struct rockchip_drm_sub_dev {
struct list_head list;
struct drm_connector *connector;
struct device_node *of_node;
void (*loader_protect)(struct drm_encoder *encoder, bool on);
};
struct rockchip_sdr2hdr_state {
@@ -162,6 +165,7 @@ struct rockchip_crtc_funcs {
* @mm_lock: protect drm_mm on multi-threads.
*/
struct rockchip_drm_private {
struct rockchip_logo *logo;
struct drm_fb_helper *fbdev_helper;
struct drm_gem_object *fbdev_bo;
struct iommu_domain *domain;
@@ -184,6 +188,12 @@ struct rockchip_drm_private {
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct rockchip_drm_vcnt vcnt[ROCKCHIP_MAX_CRTC];
/**
* @loader_protect
* ignore restore_fbdev_mode_atomic when in logo on state
*/
bool loader_protect;
dma_addr_t cubic_lut_dma_addr;
void *cubic_lut_kvaddr;
struct loader_cubic_lut cubic_lut[ROCKCHIP_MAX_CRTC];

View File

@@ -29,8 +29,6 @@ static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
{
int i = 0;
for (i = 0; i < 4; i++)
drm_gem_object_put(fb->obj[i]);
drm_framebuffer_cleanup(fb);
if (is_rockchip_logo_fb(fb)) {
@@ -38,6 +36,11 @@ static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
kfree(rockchip_logo_fb);
} else {
for (i = 0; i < 4; i++) {
if (fb->obj[i])
drm_gem_object_put(fb->obj[i]);
}
kfree(fb);
}
}
@@ -103,6 +106,9 @@ rockchip_drm_logo_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2
fb->flags |= ROCKCHIP_DRM_MODE_LOGO_FB;
rockchip_logo_fb->logo = logo;
rockchip_logo_fb->fb.obj[0] = &rockchip_logo_fb->rk_obj.base;
rockchip_logo_fb->rk_obj.dma_addr = logo->dma_addr;
rockchip_logo_fb->rk_obj.kvaddr = logo->kvaddr;
logo->count++;
return &rockchip_logo_fb->fb;
@@ -196,7 +202,7 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
}
if (drm_is_afbc(mode_cmd->modifier[0])) {
int ret, i;
int i;
ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
if (ret) {
@@ -213,9 +219,18 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
return &afbc_fb->base;
}
static void rockchip_drm_output_poll_changed(struct drm_device *dev)
{
struct rockchip_drm_private *private = dev->dev_private;
struct drm_fb_helper *fb_helper = private->fbdev_helper;
if (fb_helper && dev->mode_config.poll_enabled && !private->loader_protect)
drm_fb_helper_hotplug_event(fb_helper);
}
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
.fb_create = rockchip_fb_create,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.output_poll_changed = rockchip_drm_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};

View File

@@ -7,6 +7,8 @@
#ifndef _ROCKCHIP_DRM_FB_H
#define _ROCKCHIP_DRM_FB_H
#include "rockchip_drm_gem.h"
#define ROCKCHIP_DRM_MODE_LOGO_FB (1<<31) /* used for kernel logo, follow the define: DRM_MODE_FB_MODIFIERS at drm_mode.h */
struct drm_framebuffer *
@@ -25,6 +27,7 @@ rockchip_drm_logo_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2
struct rockchip_drm_logo_fb {
struct drm_framebuffer fb;
struct rockchip_logo *logo;
struct rockchip_gem_object rk_obj;
};
#endif /* _ROCKCHIP_DRM_FB_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2021 Rockchip Electronics Co., Ltd.
* Author: Sandy Huang <hjc@rock-chips.com>
*/
#ifndef ROCKCHIP_DRM_LOGO_H
#define ROCKCHIP_DRM_LOGO_H
struct rockchip_drm_mode_set {
struct list_head head;
struct drm_framebuffer *fb;
struct rockchip_drm_sub_dev *sub_dev;
struct drm_crtc *crtc;
struct drm_display_mode *mode;
int clock;
int hdisplay;
int vdisplay;
int vrefresh;
int flags;
int picture_aspect_ratio;
int crtc_hsync_end;
int crtc_vsync_end;
int left_margin;
int right_margin;
int top_margin;
int bottom_margin;
unsigned int brightness;
unsigned int contrast;
unsigned int saturation;
unsigned int hue;
bool mode_changed;
int ratio;
};
void rockchip_drm_show_logo(struct drm_device *drm_dev);
#endif