From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 690 ++++++++++++++++++--------------------------------------
1 files changed, 225 insertions(+), 465 deletions(-)
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index c653900..91cb119 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -1,191 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
* Author:Mark Yao <mark.yao@rock-chips.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
*/
#include <linux/kernel.h>
+#include <linux/devfreq.h>
+
#include <drm/drm.h>
-#include <drm/drmP.h>
#include <drm/drm_atomic.h>
+#include <drm/drm_damage_helper.h>
#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fourcc.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include <linux/memblock.h>
+#include <drm/drm_probe_helper.h>
#include <soc/rockchip/rockchip_dmc.h>
#include "rockchip_drm_drv.h"
#include "rockchip_drm_fb.h"
#include "rockchip_drm_gem.h"
-#include "rockchip_drm_psr.h"
+#include "rockchip_drm_logo.h"
-bool rockchip_fb_is_logo(struct drm_framebuffer *fb)
+static bool is_rockchip_logo_fb(struct drm_framebuffer *fb)
{
- struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
-
- return rk_fb && rk_fb->logo;
+ return fb->flags & ROCKCHIP_DRM_MODE_LOGO_FB ? true : false;
}
-dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb,
- unsigned int plane)
+static void __rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
{
- struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
+ int i = 0;
- if (WARN_ON(plane >= ROCKCHIP_MAX_FB_BUFFER))
- return 0;
+ drm_framebuffer_cleanup(fb);
- return rk_fb->dma_addr[plane];
+ if (is_rockchip_logo_fb(fb)) {
+ struct rockchip_drm_logo_fb *rockchip_logo_fb = to_rockchip_logo_fb(fb);
+
+#ifndef MODULE
+ rockchip_free_loader_memory(fb->dev);
+#endif
+ drm_gem_object_release(rockchip_logo_fb->fb.obj[0]);
+ kfree(rockchip_logo_fb);
+ } else {
+ for (i = 0; i < 4; i++) {
+ if (fb->obj[i])
+ drm_gem_object_put(fb->obj[i]);
+ }
+
+ kfree(fb);
+ }
}
-void *rockchip_fb_get_kvaddr(struct drm_framebuffer *fb, unsigned int plane)
+static void rockchip_drm_fb_destroy_work(struct work_struct *work)
{
- struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
+ struct rockchip_drm_logo_fb *fb;
- if (WARN_ON(plane >= ROCKCHIP_MAX_FB_BUFFER))
- return 0;
+ fb = container_of(to_delayed_work(work), struct rockchip_drm_logo_fb, destroy_work);
- return rk_fb->kvaddr[plane];
+ __rockchip_drm_fb_destroy(&fb->fb);
}
static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
{
- struct drm_gem_object *obj;
- int i;
- struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb);
- for (i = 0; i < ROCKCHIP_MAX_FB_BUFFER; i++) {
- obj = rockchip_fb->obj[i];
- if (obj)
- drm_gem_object_unreference_unlocked(obj);
+ if (is_rockchip_logo_fb(fb)) {
+ struct rockchip_drm_logo_fb *rockchip_logo_fb = to_rockchip_logo_fb(fb);
+
+ schedule_delayed_work(&rockchip_logo_fb->destroy_work, HZ);
+ } else {
+ __rockchip_drm_fb_destroy(fb);
}
-
-#ifndef MODULE
- if (rockchip_fb->logo)
- rockchip_free_loader_memory(fb->dev);
-#else
- WARN_ON(rockchip_fb->logo);
-#endif
-
- drm_framebuffer_cleanup(fb);
- kfree(rockchip_fb);
}
-static int rockchip_drm_fb_create_handle(struct drm_framebuffer *fb,
- struct drm_file *file_priv,
- unsigned int *handle)
+static int rockchip_drm_gem_fb_create_handle(struct drm_framebuffer *fb,
+ struct drm_file *file,
+ unsigned int *handle)
{
- struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb);
-
- if (rockchip_fb_is_logo(fb))
+ if (is_rockchip_logo_fb(fb))
return -EOPNOTSUPP;
- return drm_gem_handle_create(file_priv,
- rockchip_fb->obj[0], handle);
-}
-
-static int rockchip_drm_fb_dirty(struct drm_framebuffer *fb,
- struct drm_file *file,
- unsigned int flags, unsigned int color,
- struct drm_clip_rect *clips,
- unsigned int num_clips)
-{
- rockchip_drm_psr_flush_all(fb->dev);
- return 0;
+ return drm_gem_fb_create_handle(fb, file, handle);
}
static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
.destroy = rockchip_drm_fb_destroy,
- .create_handle = rockchip_drm_fb_create_handle,
- .dirty = rockchip_drm_fb_dirty,
+ .create_handle = rockchip_drm_gem_fb_create_handle,
};
struct drm_framebuffer *
rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_object **obj, struct rockchip_logo *logo,
- unsigned int num_planes)
-{
- struct rockchip_drm_fb *rockchip_fb;
- struct rockchip_gem_object *rk_obj;
- struct rockchip_drm_private *private = dev->dev_private;
- struct drm_fb_helper *fb_helper = private->fbdev_helper;
- int ret = 0;
- int i;
-
- rockchip_fb = kzalloc(sizeof(*rockchip_fb), GFP_KERNEL);
- if (!rockchip_fb)
- return ERR_PTR(-ENOMEM);
-
- drm_helper_mode_fill_fb_struct(dev, &rockchip_fb->fb, mode_cmd);
-
- ret = drm_framebuffer_init(dev, &rockchip_fb->fb,
- &rockchip_drm_fb_funcs);
- if (ret) {
- dev_err(dev->dev, "Failed to initialize framebuffer: %d\n",
- ret);
- goto err_free_fb;
- }
-
- if (obj) {
- for (i = 0; i < num_planes; i++)
- rockchip_fb->obj[i] = obj[i];
-
- for (i = 0; i < num_planes; i++) {
- rk_obj = to_rockchip_obj(obj[i]);
- rockchip_fb->dma_addr[i] = rk_obj->dma_addr;
- rockchip_fb->kvaddr[i] = rk_obj->kvaddr;
- private->fbdev_bo = &rk_obj->base;
- if (fb_helper && fb_helper->fbdev && rk_obj->kvaddr)
- fb_helper->fbdev->screen_base = rk_obj->kvaddr;
- }
-#ifndef MODULE
- } else if (logo) {
- rockchip_fb->dma_addr[0] = logo->dma_addr;
- rockchip_fb->kvaddr[0] = logo->kvaddr;
- rockchip_fb->logo = logo;
- logo->count++;
-#endif
- } else {
- ret = -EINVAL;
- dev_err(dev->dev, "Failed to find available buffer\n");
- goto err_deinit_drm_fb;
- }
-
- return &rockchip_fb->fb;
-
-err_deinit_drm_fb:
- drm_framebuffer_cleanup(&rockchip_fb->fb);
-err_free_fb:
- kfree(rockchip_fb);
- return ERR_PTR(ret);
-}
-
-static struct drm_framebuffer *
-rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
- const struct drm_mode_fb_cmd2 *mode_cmd)
+ struct drm_gem_object **obj, unsigned int num_planes)
{
struct drm_framebuffer *fb;
- struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
- struct drm_gem_object *obj;
- unsigned int hsub;
- unsigned int vsub;
- int num_planes;
int ret;
int i;
- hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
- vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
- num_planes = min(drm_format_num_planes(mode_cmd->pixel_format),
- ROCKCHIP_MAX_FB_BUFFER);
+ fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+ if (!fb)
+ return ERR_PTR(-ENOMEM);
- for (i = 0; i < num_planes; ++i) {
+ drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+ for (i = 0; i < num_planes; i++)
+ fb->obj[i] = obj[i];
+
+ ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs);
+ if (ret) {
+ DRM_DEV_ERROR(dev->dev,
+ "Failed to initialize framebuffer: %d\n",
+ ret);
+ kfree(fb);
+ return ERR_PTR(ret);
+ }
+
+ return fb;
+}
+
+struct drm_framebuffer *
+rockchip_drm_logo_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd,
+ struct rockchip_logo *logo)
+{
+ int ret = 0;
+ struct rockchip_drm_logo_fb *rockchip_logo_fb;
+ struct drm_framebuffer *fb;
+
+ rockchip_logo_fb = kzalloc(sizeof(*rockchip_logo_fb), GFP_KERNEL);
+ if (!rockchip_logo_fb)
+ return ERR_PTR(-ENOMEM);
+ fb = &rockchip_logo_fb->fb;
+
+ drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+ ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs);
+ if (ret) {
+ DRM_DEV_ERROR(dev->dev,
+ "Failed to initialize rockchip logo fb: %d\n",
+ ret);
+ kfree(rockchip_logo_fb);
+ return ERR_PTR(ret);
+ }
+
+ fb->flags |= ROCKCHIP_DRM_MODE_LOGO_FB;
+ rockchip_logo_fb->logo = logo;
+ rockchip_logo_fb->fb.obj[0] = &rockchip_logo_fb->rk_obj.base;
+ drm_gem_object_init(dev, rockchip_logo_fb->fb.obj[0], PAGE_ALIGN(logo->size));
+ rockchip_logo_fb->rk_obj.dma_addr = logo->dma_addr;
+ rockchip_logo_fb->rk_obj.kvaddr = logo->kvaddr;
+ logo->count++;
+ INIT_DELAYED_WORK(&rockchip_logo_fb->destroy_work, rockchip_drm_fb_destroy_work);
+ return &rockchip_logo_fb->fb;
+}
+
+static int rockchip_drm_bandwidth_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ struct dmcfreq_vop_info *vop_bw_info)
+{
+ struct rockchip_drm_private *priv = dev->dev_private;
+ struct drm_crtc_state *old_crtc_state;
+ const struct rockchip_crtc_funcs *funcs;
+ struct drm_crtc *crtc;
+ int i;
+
+ vop_bw_info->line_bw_mbyte = 0;
+ vop_bw_info->frame_bw_mbyte = 0;
+ vop_bw_info->plane_num = 0;
+ vop_bw_info->plane_num_4k = 0;
+
+ for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
+ funcs = priv->crtc_funcs[drm_crtc_index(crtc)];
+
+ if (funcs && funcs->bandwidth)
+ funcs->bandwidth(crtc, old_crtc_state, vop_bw_info);
+ }
+
+ return 0;
+}
+
+static void drm_atomic_helper_connector_commit(struct drm_device *dev,
+ struct drm_atomic_state *old_state)
+{
+ struct drm_connector *connector;
+ struct drm_connector_state *new_conn_state;
+ int i;
+
+ for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
+ const struct drm_connector_helper_funcs *funcs;
+
+ funcs = connector->helper_private;
+ if (!funcs->atomic_commit)
+ continue;
+
+ funcs->atomic_commit(connector, new_conn_state);
+ }
+}
+
+/**
+ * rockchip_drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
+ * @old_state: new modeset state to be committed
+ *
+ * This is an alternative implementation for the
+ * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
+ * that support runtime_pm or need the CRTC to be enabled to perform a
+ * commit. Otherwise, one should use the default implementation
+ * drm_atomic_helper_commit_tail().
+ */
+static void rockchip_drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
+{
+ struct drm_device *dev = old_state->dev;
+ struct rockchip_drm_private *prv = dev->dev_private;
+ struct dmcfreq_vop_info vop_bw_info;
+
+ drm_atomic_helper_commit_modeset_disables(dev, old_state);
+
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+ rockchip_drm_bandwidth_atomic_check(dev, old_state, &vop_bw_info);
+
+ rockchip_dmcfreq_vop_bandwidth_update(&vop_bw_info);
+
+ mutex_lock(&prv->ovl_lock);
+ drm_atomic_helper_commit_planes(dev, old_state, DRM_PLANE_COMMIT_ACTIVE_ONLY);
+ mutex_unlock(&prv->ovl_lock);
+
+ drm_atomic_helper_fake_vblank(old_state);
+
+ drm_atomic_helper_connector_commit(dev, old_state);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+
+ drm_atomic_helper_wait_for_vblanks(dev, old_state);
+
+ drm_atomic_helper_cleanup_planes(dev, old_state);
+}
+
+static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
+ .atomic_commit_tail = rockchip_drm_atomic_helper_commit_tail_rpm,
+};
+
+static struct drm_framebuffer *
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ struct drm_afbc_framebuffer *afbc_fb;
+ const struct drm_format_info *info;
+ int ret, i;
+
+ info = drm_get_format_info(dev, mode_cmd);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < info->num_planes; ++i) {
if (mode_cmd->pitches[i] % 4) {
DRM_DEV_ERROR_RATELIMITED(dev->dev,
"fb pitch[%d] must be 4 byte aligned: %d\n", i, mode_cmd->pitches[i]);
@@ -193,43 +256,31 @@
}
}
- for (i = 0; i < num_planes; i++) {
- unsigned int width = mode_cmd->width / (i ? hsub : 1);
- unsigned int height = mode_cmd->height / (i ? vsub : 1);
- unsigned int min_size;
+ afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+ if (!afbc_fb)
+ return ERR_PTR(-ENOMEM);
- obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
- if (!obj) {
- DRM_DEV_ERROR(dev->dev,
- "Failed to lookup GEM object\n");
- ret = -ENXIO;
- goto err_gem_object_unreference;
- }
-
- min_size = (height - 1) * mode_cmd->pitches[i] +
- mode_cmd->offsets[i] +
- width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
-
- if (obj->size < min_size) {
- drm_gem_object_put_unlocked(obj);
- ret = -EINVAL;
- goto err_gem_object_unreference;
- }
- objs[i] = obj;
+ ret = drm_gem_fb_init_with_funcs(dev, &afbc_fb->base, file, mode_cmd,
+ &rockchip_drm_fb_funcs);
+ if (ret) {
+ kfree(afbc_fb);
+ return ERR_PTR(ret);
}
- fb = rockchip_fb_alloc(dev, mode_cmd, objs, NULL, i);
- if (IS_ERR(fb)) {
- ret = PTR_ERR(fb);
- goto err_gem_object_unreference;
+ if (drm_is_afbc(mode_cmd->modifier[0])) {
+ ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
+ if (ret) {
+ struct drm_gem_object **obj = afbc_fb->base.obj;
+
+ for (i = 0; i < info->num_planes; ++i)
+ drm_gem_object_put(obj[i]);
+
+ kfree(afbc_fb);
+ return ERR_PTR(ret);
+ }
}
- return fb;
-
-err_gem_object_unreference:
- for (i--; i >= 0; i--)
- drm_gem_object_put_unlocked(objs[i]);
- return ERR_PTR(ret);
+ return &afbc_fb->base;
}
static void rockchip_drm_output_poll_changed(struct drm_device *dev)
@@ -241,302 +292,11 @@
drm_fb_helper_hotplug_event(fb_helper);
}
-static int rockchip_drm_bandwidth_atomic_check(struct drm_device *dev,
- struct drm_atomic_state *state,
- size_t *line_bw_mbyte,
- size_t *frame_bw_mbyte,
- unsigned int *plane_num)
-{
- struct rockchip_drm_private *priv = dev->dev_private;
- struct drm_crtc_state *crtc_state;
- const struct rockchip_crtc_funcs *funcs;
- struct drm_crtc *crtc;
- int i, ret = 0;
-
- *line_bw_mbyte = 0;
- *frame_bw_mbyte = 0;
- *plane_num = 0;
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- funcs = priv->crtc_funcs[drm_crtc_index(crtc)];
-
- if (funcs && funcs->bandwidth)
- *line_bw_mbyte += funcs->bandwidth(crtc, crtc_state,
- frame_bw_mbyte,
- plane_num);
- }
-
- /*
- * Check ddr frequency support here here.
- */
- if (priv->dmc_support && !priv->devfreq) {
- priv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0);
- if (IS_ERR(priv->devfreq))
- priv->devfreq = NULL;
- }
-
- if (priv->devfreq)
- ret = rockchip_dmcfreq_vop_bandwidth_request(priv->devfreq,
- *line_bw_mbyte);
-
- return ret;
-}
-
-static void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state)
-{
- struct drm_crtc *crtc;
- struct drm_crtc_state *crtc_state;
- struct drm_encoder *encoder;
- u32 encoder_mask = 0;
- int i;
-
- for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
- encoder_mask |= crtc_state->encoder_mask;
- encoder_mask |= crtc->state->encoder_mask;
- }
-
- drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
- rockchip_drm_psr_inhibit_get(encoder);
-}
-
-static void
-rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state)
-{
- struct drm_crtc *crtc;
- struct drm_crtc_state *crtc_state;
- struct drm_encoder *encoder;
- u32 encoder_mask = 0;
- int i;
-
- for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
- encoder_mask |= crtc_state->encoder_mask;
- encoder_mask |= crtc->state->encoder_mask;
- }
-
- drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
- rockchip_drm_psr_inhibit_put(encoder);
-}
-
-static void
-rockchip_drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
- struct drm_atomic_state *old_state)
-{
- struct drm_crtc *crtc;
- struct drm_crtc_state *old_crtc_state, *new_crtc_state;
- int i, ret;
- unsigned int crtc_mask = 0;
- struct rockchip_crtc_state *s;
-
- /*
- * Legacy cursor ioctls are completely unsynced, and userspace
- * relies on that (by doing tons of cursor updates).
- */
- if (old_state->legacy_cursor_update)
- return;
-
- for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
- if (!new_crtc_state->active)
- continue;
-
- ret = drm_crtc_vblank_get(crtc);
- if (ret != 0)
- continue;
-
- crtc_mask |= drm_crtc_mask(crtc);
- old_state->crtcs[i].last_vblank_count =
- drm_crtc_vblank_count(crtc);
- }
-
- for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
- if (!(crtc_mask & drm_crtc_mask(crtc)))
- continue;
-
- ret = wait_event_timeout(dev->vblank[i].queue,
- old_state->crtcs[i].last_vblank_count !=
- drm_crtc_vblank_count(crtc),
- msecs_to_jiffies(50));
-
- s = to_rockchip_crtc_state(crtc->state);
-
- if (!s->mode_update && !ret)
- DRM_WARN("[CRTC:%d:%s] state:%d, vblank wait timed out\n",
- crtc->base.id, crtc->name, old_crtc_state->active);
-
- drm_crtc_vblank_put(crtc);
- s->mode_update = false;
- }
-}
-
-static void
-rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
-{
- struct drm_device *dev = old_state->dev;
-
- rockchip_drm_psr_inhibit_get_state(old_state);
-
- drm_atomic_helper_commit_modeset_disables(dev, old_state);
-
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
-
- drm_atomic_helper_commit_planes(dev, old_state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
- rockchip_drm_psr_inhibit_put_state(old_state);
-
- drm_atomic_helper_commit_hw_done(old_state);
-
- rockchip_drm_atomic_helper_wait_for_vblanks(dev, old_state);
-
- drm_atomic_helper_cleanup_planes(dev, old_state);
-}
-
-static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
- .atomic_commit_tail = rockchip_atomic_helper_commit_tail_rpm,
-};
-
-static void
-rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
-{
- struct drm_atomic_state *state = commit->state;
- struct drm_device *dev = commit->dev;
- struct rockchip_drm_private *prv = dev->dev_private;
- size_t line_bw_mbyte = commit->line_bw_mbyte;
- size_t frame_bw_mbyte = commit->frame_bw_mbyte;
- unsigned int plane_num = commit->plane_num;
-
- /*
- * TODO: do fence wait here.
- */
-
- /*
- * Rockchip crtc support runtime PM, can't update display planes
- * when crtc is disabled.
- *
- * drm_atomic_helper_commit comments detail that:
- * For drivers supporting runtime PM the recommended sequence is
- *
- * drm_atomic_helper_commit_modeset_disables(dev, state);
- *
- * drm_atomic_helper_commit_modeset_enables(dev, state);
- *
- * drm_atomic_helper_commit_planes(dev, state, true);
- *
- * See the kerneldoc entries for these three functions for more details.
- */
- drm_atomic_helper_wait_for_dependencies(state);
-
- rockchip_drm_psr_inhibit_get_state(state);
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- if (prv->dmc_support && !prv->devfreq) {
- prv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0);
- if (IS_ERR(prv->devfreq))
- prv->devfreq = NULL;
- }
- if (prv->devfreq)
- rockchip_dmcfreq_vop_bandwidth_update(prv->devfreq, line_bw_mbyte, frame_bw_mbyte,
- plane_num);
-
- mutex_lock(&prv->ovl_lock);
- drm_atomic_helper_commit_planes(dev, state, true);
- mutex_unlock(&prv->ovl_lock);
-
- rockchip_drm_psr_inhibit_put_state(state);
-
- drm_atomic_helper_commit_hw_done(state);
-
- rockchip_drm_atomic_helper_wait_for_vblanks(dev, state);
-
- drm_atomic_helper_cleanup_planes(dev, state);
-
- drm_atomic_helper_commit_cleanup_done(state);
-
- drm_atomic_state_put(state);
-
- kfree(commit);
-}
-
-void rockchip_drm_atomic_work(struct work_struct *work)
-{
- struct rockchip_drm_private *private = container_of(work,
- struct rockchip_drm_private, commit_work);
-
- rockchip_atomic_commit_complete(private->commit);
- private->commit = NULL;
-}
-
-static int rockchip_drm_atomic_commit(struct drm_device *dev,
- struct drm_atomic_state *state,
- bool async)
-{
- struct rockchip_drm_private *private = dev->dev_private;
- struct rockchip_atomic_commit *commit;
- size_t line_bw_mbyte;
- size_t frame_bw_mbyte;
- unsigned int plane_num;
- int ret;
-
- ret = drm_atomic_helper_setup_commit(state, false);
- if (ret)
- return ret;
-
- ret = drm_atomic_helper_prepare_planes(dev, state);
- if (ret)
- return ret;
-
- ret = rockchip_drm_bandwidth_atomic_check(dev, state,
- &line_bw_mbyte,
- &frame_bw_mbyte,
- &plane_num);
- if (ret) {
- /*
- * TODO:
- * Just report bandwidth can't support now.
- */
- DRM_ERROR("vop bandwidth too large %zd\n", line_bw_mbyte);
- }
-
- ret = drm_atomic_helper_swap_state(state, true);
- if (ret < 0) {
- DRM_ERROR("swap atomic state for %s failed: %d\n", current->comm, ret);
- drm_atomic_helper_cleanup_planes(dev, state);
- return ret;
- }
-
- drm_atomic_state_get(state);
- commit = kmalloc(sizeof(*commit), GFP_KERNEL);
- if (!commit)
- return -ENOMEM;
-
- commit->dev = dev;
- commit->state = state;
- commit->line_bw_mbyte = line_bw_mbyte;
- commit->frame_bw_mbyte = frame_bw_mbyte;
- commit->plane_num = plane_num;
-
- if (async) {
- mutex_lock(&private->commit_lock);
-
- flush_work(&private->commit_work);
- WARN_ON(private->commit);
- private->commit = commit;
- schedule_work(&private->commit_work);
-
- mutex_unlock(&private->commit_lock);
- } else {
- rockchip_atomic_commit_complete(commit);
- }
-
- return 0;
-}
-
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
- .fb_create = rockchip_user_fb_create,
+ .fb_create = rockchip_fb_create,
.output_poll_changed = rockchip_drm_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
- .atomic_commit = rockchip_drm_atomic_commit,
+ .atomic_commit = drm_atomic_helper_commit,
};
struct drm_framebuffer *
@@ -546,7 +306,7 @@
{
struct drm_framebuffer *fb;
- fb = rockchip_fb_alloc(dev, mode_cmd, &obj, NULL, 1);
+ fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1);
if (IS_ERR(fb))
return ERR_CAST(fb);
@@ -559,12 +319,12 @@
dev->mode_config.min_height = 0;
/*
- * set max width and height as default value(4096x4096).
+ * set max width and height as default value(16384x16384).
* this value would be used to check framebuffer size limitation
* at drm_mode_addfb().
*/
- dev->mode_config.max_width = 8192;
- dev->mode_config.max_height = 8192;
+ dev->mode_config.max_width = 16384;
+ dev->mode_config.max_height = 16384;
dev->mode_config.async_page_flip = true;
dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
--
Gitblit v1.6.2