Skip to content

Commit

Permalink
riscv: drm: dc: boost desktop performance upto 4k30fps
Browse files Browse the repository at this point in the history
update dc logic to boost desktop performance upto 4k30fps

Signed-off-by: keith.zhao <[email protected]>
  • Loading branch information
starfivesyangc authored and MichaIng committed Dec 8, 2023
1 parent e5c58f2 commit 071aae0
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 79 deletions.
153 changes: 79 additions & 74 deletions drivers/gpu/drm/verisilicon/vs_dc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1242,79 +1242,24 @@ static void update_cursor_size(struct drm_plane_state *state, struct dc_hw_curso
cursor->size = size_type;
}

static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, struct drm_plane *drm_plane,
struct drm_atomic_state *drm_state)
{
//struct drm_plane_state *state = plane->base.state;
struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state,
drm_plane);
struct drm_framebuffer *drm_fb = state->fb;
struct dc_hw_cursor cursor;
static u32 pre_address = 0;

cursor.address = plane->dma_addr[0];
cursor.x = state->crtc_x;
cursor.y = state->crtc_y;
cursor.hot_x = drm_fb->hot_x;
cursor.hot_y = drm_fb->hot_y;
cursor.display_id = to_vs_display_id(dc, state->crtc);
update_cursor_size(state, &cursor);
cursor.enable = true;

if (cursor.address != pre_address) {
sifive_l2_flush64_range(cursor.address, ((cursor.size == CURSOR_SIZE_32X32) ?
CURSOR_MEM_SIZE_32X32 : CURSOR_MEM_SIZE_64X64));
pre_address = cursor.address;
}

dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
}

static void vs_dc_update_plane(struct device *dev, struct vs_plane *plane, struct drm_plane *drm_plane,
struct drm_atomic_state *drm_state)
{
struct vs_dc *dc = dev_get_drvdata(dev);
enum drm_plane_type type = plane->base.type;

switch (type) {
case DRM_PLANE_TYPE_PRIMARY:
case DRM_PLANE_TYPE_OVERLAY:
update_plane(dc, plane, drm_plane, drm_state);
update_qos(dc, plane, drm_plane, drm_state);
break;
case DRM_PLANE_TYPE_CURSOR:
update_cursor_plane(dc, plane, drm_plane, drm_state);
break;
default:
break;
}
update_plane(dc, plane, drm_plane, drm_state);
update_qos(dc, plane, drm_plane, drm_state);

}

static void vs_dc_disable_plane(struct device *dev, struct vs_plane *plane,
struct drm_plane_state *old_state)
{
struct vs_dc *dc = dev_get_drvdata(dev);
enum drm_plane_type type = plane->base.type;
struct dc_hw_fb fb = {0};
struct dc_hw_cursor cursor = {0};

switch (type) {
case DRM_PLANE_TYPE_PRIMARY:
case DRM_PLANE_TYPE_OVERLAY:
fb.enable = false;
dc_hw_update_plane(&dc->hw, plane->id, &fb, NULL, NULL, NULL);
#ifdef CONFIG_VERISILICON_DEC
disable_fbc(dc, plane);
#endif
break;
case DRM_PLANE_TYPE_CURSOR:
cursor.enable = false;
cursor.display_id = to_vs_display_id(dc, old_state->crtc);
dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
break;
default:
break;
}
fb.enable = false;
dc_hw_update_plane(&dc->hw, plane->id, &fb, NULL, NULL, NULL);
}

static bool vs_dc_mod_supported(const struct vs_plane_info *plane_info,
Expand Down Expand Up @@ -1372,6 +1317,80 @@ static int vs_dc_check_plane(struct device *dev, struct drm_plane *plane,
true, true);
}

static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
struct drm_plane *drm_plane,
struct drm_atomic_state *drm_state)
{
struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state,
drm_plane);
struct drm_framebuffer *drm_fb = state->fb;
struct dc_hw_cursor cursor;
static u32 pre_address = 0;

cursor.address = plane->dma_addr[0];
cursor.x = state->crtc_x;
cursor.y = state->crtc_y;
cursor.hot_x = drm_fb->hot_x;
cursor.hot_y = drm_fb->hot_y;
cursor.display_id = to_vs_display_id(dc, state->crtc);
update_cursor_size(state, &cursor);
cursor.enable = true;

if (cursor.address != pre_address) {
sifive_l2_flush64_range(cursor.address, ((cursor.size == CURSOR_SIZE_32X32) ?
CURSOR_MEM_SIZE_32X32 : CURSOR_MEM_SIZE_64X64));
pre_address = cursor.address;
}

dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
}

void vs_dc_update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
struct drm_plane *drm_plane,
struct drm_atomic_state *drm_state)
{
update_cursor_plane(dc, plane, drm_plane, drm_state);
}

void vs_dc_disable_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
struct drm_plane_state *old_state)
{
struct dc_hw_cursor cursor = {0};

cursor.enable = false;
cursor.display_id = to_vs_display_id(dc, old_state->crtc);
dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
}

int vs_dc_check_cursor_plane(struct vs_dc *dc, struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
struct drm_framebuffer *fb = new_plane_state->fb;
const struct vs_plane_info *plane_info;
struct drm_crtc *crtc = new_plane_state->crtc;
struct drm_crtc_state *crtc_state;
struct vs_plane *vs_plane = to_vs_plane(plane);

plane_info = &dc->hw.info->planes[vs_plane->id];

if (fb->width < plane_info->min_width ||
fb->width > plane_info->max_width ||
fb->height < plane_info->min_height ||
fb->height > plane_info->max_height)
drm_err_once(plane->dev, "buffer size may not support on plane%d.\n", vs_plane->id);

crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
return -EINVAL;

return drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
plane_info->min_scale,
plane_info->max_scale,
true, true);
}

static irqreturn_t dc_isr(int irq, void *data)
{
struct vs_dc *dc = data;
Expand Down Expand Up @@ -1457,20 +1476,6 @@ static int dc_bind(struct device *dev, struct device *master, void *data)
return ret;
}

#ifdef CONFIG_VERISILICON_MMU
ret = dc_mmu_construct(priv->dma_dev, &priv->mmu);
if (ret) {
dev_err(dev, "failed to construct DC MMU\n");
goto err_clean_dc;
}

ret = dc_hw_mmu_init(&dc->hw, priv->mmu);
if (ret) {
dev_err(dev, "failed to init DC MMU\n");
goto err_clean_dc;
}
#endif

ret = vs_drm_iommu_attach_device(drm_dev, dev);
if (ret < 0) {
dev_err(dev, "Failed to attached iommu device.\n");
Expand Down
9 changes: 9 additions & 0 deletions drivers/gpu/drm/verisilicon/vs_dc.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,13 @@ struct vs_dc {
extern struct platform_driver dc_platform_driver;
extern void sifive_l2_flush64_range(unsigned long start, unsigned long len);

void vs_dc_update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
struct drm_plane *drm_plane,
struct drm_atomic_state *drm_state);
void vs_dc_disable_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
struct drm_plane_state *old_state);
int vs_dc_check_cursor_plane(struct vs_dc *dc, struct drm_plane *plane,
struct drm_atomic_state *state);


#endif /* __VS_DC_H__ */
94 changes: 89 additions & 5 deletions drivers/gpu/drm/verisilicon/vs_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "vs_plane.h"
#include "vs_gem.h"
#include "vs_fb.h"
#include "vs_dc.h"

void vs_plane_destory(struct drm_plane *plane)
{
Expand Down Expand Up @@ -312,12 +313,90 @@ static void vs_plane_atomic_disable(struct drm_plane *plane,
vs_plane->funcs->disable(vs_crtc->dev, vs_plane, old_state);
}

const struct drm_plane_helper_funcs vs_plane_helper_funcs = {
.atomic_check = vs_plane_atomic_check,
.atomic_update = vs_plane_atomic_update,
.atomic_disable = vs_plane_atomic_disable,
static void vs_cursor_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
plane);
struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
plane);
unsigned char i, num_planes;
struct drm_framebuffer *fb;
struct vs_plane *vs_plane = to_vs_plane(plane);
struct vs_crtc *vs_crtc = to_vs_crtc(new_state->crtc);
struct vs_plane_state *plane_state = to_vs_plane_state(new_state);
struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);

if (!new_state->fb || !new_state->crtc)
return;

fb = new_state->fb;

num_planes = vs_get_plane_number(fb);

for (i = 0; i < num_planes; i++) {
struct vs_gem_object *vs_obj;

vs_obj = vs_fb_get_gem_obj(fb, i);
vs_plane->dma_addr[i] = vs_obj->iova + fb->offsets[i];
}

plane_state->status.src = drm_plane_state_src(new_state);
plane_state->status.dest = drm_plane_state_dest(new_state);

vs_dc_update_cursor_plane(dc, vs_plane, plane, state);
}

static void vs_cursor_plane_atomic_disable(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
plane);
struct vs_plane *vs_plane = to_vs_plane(plane);
struct vs_crtc *vs_crtc = to_vs_crtc(old_state->crtc);
struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);

vs_dc_disable_cursor_plane(dc, vs_plane, old_state);
}


static int vs_cursor_plane_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
unsigned char i, num_planes;
struct drm_framebuffer *fb = new_plane_state->fb;
struct drm_crtc *crtc = new_plane_state->crtc;
struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
struct vs_plane_state *plane_state = to_vs_plane_state(new_plane_state);

if (!crtc || !fb)
return 0;

return vs_dc_check_cursor_plane(dc, plane, state);
}

const struct drm_plane_helper_funcs primary_plane_helpers = {
.atomic_check = vs_plane_atomic_check,
.atomic_update = vs_plane_atomic_update,
.atomic_disable = vs_plane_atomic_disable,
};

const struct drm_plane_helper_funcs overlay_plane_helpers = {
.atomic_check = vs_plane_atomic_check,
.atomic_update = vs_plane_atomic_update,
.atomic_disable = vs_plane_atomic_disable,
};

const struct drm_plane_helper_funcs cursor_plane_helpers = {
.atomic_check = vs_cursor_plane_atomic_check,
.atomic_update = vs_cursor_plane_atomic_update,
.atomic_disable = vs_cursor_plane_atomic_disable,
};


static const struct drm_prop_enum_list vs_degamma_mode_enum_list[] = {
{ VS_DEGAMMA_DISABLE, "disabled" },
{ VS_DEGAMMA_BT709, "preset degamma for BT709" },
Expand Down Expand Up @@ -346,7 +425,12 @@ struct vs_plane *vs_plane_create(struct drm_device *drm_dev,
if (ret)
goto err_free_plane;

drm_plane_helper_add(&plane->base, &vs_plane_helper_funcs);
if (info->type == DRM_PLANE_TYPE_PRIMARY)
drm_plane_helper_add(&plane->base, &primary_plane_helpers);
else if (info->type == DRM_PLANE_TYPE_CURSOR)
drm_plane_helper_add(&plane->base, &cursor_plane_helpers);
else
drm_plane_helper_add(&plane->base, &overlay_plane_helpers);

/* Set up the plane properties */
if (info->degamma_size) {
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/verisilicon/vs_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct vs_plane_status {
struct vs_plane_state {
struct drm_plane_state base;
struct vs_plane_status status; /* for debugfs */
dma_addr_t dma_addr[MAX_NUM_PLANES];

struct drm_property_blob *watermark;
struct drm_property_blob *color_mgmt;
Expand Down

0 comments on commit 071aae0

Please sign in to comment.