summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshengyang.chen <shengyang.chen@starfivetech.com>2023-11-10 10:34:49 +0300
committershengyang.chen <shengyang.chen@starfivetech.com>2023-11-10 11:33:53 +0300
commitf42145f5cc872d6ac3d06b72d197c9d16cab94ea (patch)
tree7c5d2fe88b53d5b3235f47a870b7fc62aeafecef
parentfcd4b4a9444b968f09a17eb9f14311eafb89bd9f (diff)
downloadlinux-f42145f5cc872d6ac3d06b72d197c9d16cab94ea.tar.xz
riscv: drm: dc: boost desktop performance upto 4k30fps
update dc logic to boost desktop performance upto 4k30fps Signed-off-by: keith.zhao <keith.zhao@starfivetech.com>
-rw-r--r--drivers/gpu/drm/verisilicon/vs_dc.c153
-rwxr-xr-xdrivers/gpu/drm/verisilicon/vs_dc.h8
-rwxr-xr-xdrivers/gpu/drm/verisilicon/vs_plane.c94
-rw-r--r--drivers/gpu/drm/verisilicon/vs_plane.h1
4 files changed, 177 insertions, 79 deletions
diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c b/drivers/gpu/drm/verisilicon/vs_dc.c
index 3bad16fcb4ba..7c9e8a16c5fc 100644
--- a/drivers/gpu/drm/verisilicon/vs_dc.c
+++ b/drivers/gpu/drm/verisilicon/vs_dc.c
@@ -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,
@@ -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;
@@ -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");
diff --git a/drivers/gpu/drm/verisilicon/vs_dc.h b/drivers/gpu/drm/verisilicon/vs_dc.h
index 061a49cc8dcc..6f183108382b 100755
--- a/drivers/gpu/drm/verisilicon/vs_dc.h
+++ b/drivers/gpu/drm/verisilicon/vs_dc.h
@@ -80,5 +80,13 @@ struct vs_dc {
extern struct platform_driver dc_platform_driver;
+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__ */
diff --git a/drivers/gpu/drm/verisilicon/vs_plane.c b/drivers/gpu/drm/verisilicon/vs_plane.c
index 8cf5f3b9d965..65ac8df0bf6d 100755
--- a/drivers/gpu/drm/verisilicon/vs_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_plane.c
@@ -15,6 +15,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)
{
@@ -309,12 +310,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" },
@@ -343,7 +422,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) {
diff --git a/drivers/gpu/drm/verisilicon/vs_plane.h b/drivers/gpu/drm/verisilicon/vs_plane.h
index ab4591d54614..3817d93d57f6 100644
--- a/drivers/gpu/drm/verisilicon/vs_plane.h
+++ b/drivers/gpu/drm/verisilicon/vs_plane.h
@@ -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;