* [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-21 17:07 [PATCH 0/3] drm/amdgpu: modernize virtual display feature Ryan Taylor
@ 2021-07-21 17:07 ` Ryan Taylor
2021-07-23 14:31 ` Alex Deucher
2021-07-21 17:07 ` [PATCH 2/3] drm/amdgpu: cleanup dce_virtual Ryan Taylor
2021-07-21 17:07 ` [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3) Ryan Taylor
2 siblings, 1 reply; 13+ messages in thread
From: Ryan Taylor @ 2021-07-21 17:07 UTC (permalink / raw)
To: dri-devel, amd-gfx
Cc: melissa.srw, daniel.vetter, rodrigo.siqueira, Ryan Taylor,
kernel test robot
Modify the VKMS driver into an api that dce_virtual can use to create
virtual displays that obey drm's atomic modesetting api.
v2: Made local functions static.
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
---
drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411 +++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 29 ++
drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
7 files changed, 458 insertions(+), 11 deletions(-)
create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index f089794bbdd5..30cbcd5ce1cc 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -120,6 +120,7 @@ amdgpu-y += \
amdgpu-y += \
dce_v10_0.o \
dce_v11_0.o \
+ amdgpu_vkms.o \
dce_virtual.o
# add GFX block
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 54cf647bd018..d0a2f2ed433d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -919,6 +919,7 @@ struct amdgpu_device {
/* display */
bool enable_virtual_display;
+ struct amdgpu_vkms_output *amdgpu_vkms_output;
struct amdgpu_mode_info mode_info;
/* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
struct work_struct hotplug_work;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index d0c935cf4f0f..1b016e5bc75f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
int ret, retry = 0;
bool supports_atomic = false;
- if (!amdgpu_virtual_display &&
+ if (amdgpu_virtual_display ||
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
supports_atomic = true;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 09b048647523..5a143ca02cf9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
}
/* disable all the possible outputs/crtcs before entering KMS mode */
- if (!amdgpu_device_has_dc_support(adev))
+ if (!amdgpu_device_has_dc_support(adev) && !amdgpu_virtual_display)
drm_helper_disable_unused_functions(adev_to_drm(adev));
drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
new file mode 100644
index 000000000000..d5c1f1c58f5f
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_vblank.h>
+
+#include "amdgpu.h"
+#include "amdgpu_vkms.h"
+#include "amdgpu_display.h"
+
+/**
+ * DOC: amdgpu_vkms
+ *
+ * The amdgpu vkms interface provides a virtual KMS interface for several use
+ * cases: devices without display hardware, platforms where the actual display
+ * hardware is not useful (e.g., servers), SR-IOV virtual functions, device
+ * emulation/simulation, and device bring up prior to display hardware being
+ * usable. We previously emulated a legacy KMS interface, but there was a desire
+ * to move to the atomic KMS interface. The vkms driver did everything we
+ * needed, but we wanted KMS support natively in the driver without buffer
+ * sharing and the ability to support an instance of VKMS per device. We first
+ * looked at splitting vkms into a stub driver and a helper module that other
+ * drivers could use to implement a virtual display, but this strategy ended up
+ * being messy due to driver specific callbacks needed for buffer management.
+ * Ultimately, it proved easier to import the vkms code as it mostly used core
+ * drm helpers anyway.
+ */
+
+static const u32 amdgpu_vkms_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
+{
+ struct amdgpu_vkms_output *output = container_of(timer,
+ struct amdgpu_vkms_output,
+ vblank_hrtimer);
+ struct drm_crtc *crtc = &output->crtc;
+ u64 ret_overrun;
+ bool ret;
+
+ ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
+ output->period_ns);
+ WARN_ON(ret_overrun != 1);
+
+ ret = drm_crtc_handle_vblank(crtc);
+ if (!ret)
+ DRM_ERROR("amdgpu_vkms failure on handling vblank");
+
+ return HRTIMER_RESTART;
+}
+
+static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ unsigned int pipe = drm_crtc_index(crtc);
+ struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+ struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
+
+ drm_calc_timestamping_constants(crtc, &crtc->mode);
+
+ hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
+ out->period_ns = ktime_set(0, vblank->framedur_ns);
+ hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
+
+ return 0;
+}
+
+static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc)
+{
+ struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
+
+ hrtimer_cancel(&out->vblank_hrtimer);
+}
+
+static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
+ int *max_error,
+ ktime_t *vblank_time,
+ bool in_vblank_irq)
+{
+ struct drm_device *dev = crtc->dev;
+ unsigned int pipe = crtc->index;
+ struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
+ struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+
+ if (!READ_ONCE(vblank->enabled)) {
+ *vblank_time = ktime_get();
+ return true;
+ }
+
+ *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
+
+ if (WARN_ON(*vblank_time == vblank->time))
+ return true;
+
+ /*
+ * To prevent races we roll the hrtimer forward before we do any
+ * interrupt processing - this is how real hw works (the interrupt is
+ * only generated after all the vblank registers are updated) and what
+ * the vblank core expects. Therefore we need to always correct the
+ * timestampe by one frame.
+ */
+ *vblank_time -= output->period_ns;
+
+ return true;
+}
+
+static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = drm_crtc_cleanup,
+ .page_flip = drm_atomic_helper_page_flip,
+ .reset = drm_atomic_helper_crtc_reset,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+ .enable_vblank = amdgpu_vkms_enable_vblank,
+ .disable_vblank = amdgpu_vkms_disable_vblank,
+ .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
+};
+
+static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ drm_crtc_vblank_on(crtc);
+}
+
+static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ drm_crtc_vblank_off(crtc);
+}
+
+static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ if (crtc->state->event) {
+ spin_lock(&crtc->dev->event_lock);
+
+ if (drm_crtc_vblank_get(crtc) != 0)
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ else
+ drm_crtc_arm_vblank_event(crtc, crtc->state->event);
+
+ spin_unlock(&crtc->dev->event_lock);
+
+ crtc->state->event = NULL;
+ }
+}
+
+static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
+ .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
+ .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
+ .atomic_disable = amdgpu_vkms_crtc_atomic_disable,
+};
+
+static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+ struct drm_plane *primary, struct drm_plane *cursor)
+{
+ int ret;
+
+ ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
+ &amdgpu_vkms_crtc_funcs, NULL);
+ if (ret) {
+ DRM_ERROR("Failed to init CRTC\n");
+ return ret;
+ }
+
+ drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
+
+ return ret;
+}
+
+static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
+{
+ int count;
+
+ count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
+ drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
+
+ return count;
+}
+
+static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
+ .get_modes = amdgpu_vkms_conn_get_modes,
+};
+
+static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = drm_plane_cleanup,
+ .reset = drm_atomic_helper_plane_reset,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ return;
+}
+
+static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct drm_crtc_state *crtc_state;
+ bool can_position = false;
+ int ret;
+
+ if (!state->fb || WARN_ON(!state->crtc))
+ return 0;
+
+ crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ ret = drm_atomic_helper_check_plane_state(state, crtc_state,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ can_position, true);
+ if (ret != 0)
+ return ret;
+
+ /* for now primary plane must be visible and full screen */
+ if (!state->visible && !can_position)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *new_state)
+{
+ struct amdgpu_framebuffer *afb;
+ struct drm_gem_object *obj;
+ struct amdgpu_device *adev;
+ struct amdgpu_bo *rbo;
+ struct list_head list;
+ struct ttm_validate_buffer tv;
+ struct ww_acquire_ctx ticket;
+ uint32_t domain;
+ int r;
+
+ if (!new_state->fb) {
+ DRM_DEBUG_KMS("No FB bound\n");
+ return 0;
+ }
+ afb = to_amdgpu_framebuffer(new_state->fb);
+ obj = new_state->fb->obj[0];
+ rbo = gem_to_amdgpu_bo(obj);
+ adev = amdgpu_ttm_adev(rbo->tbo.bdev);
+ INIT_LIST_HEAD(&list);
+
+ tv.bo = &rbo->tbo;
+ tv.num_shared = 1;
+ list_add(&tv.head, &list);
+
+ r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (r) {
+ dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+ return r;
+ }
+
+ if (plane->type != DRM_PLANE_TYPE_CURSOR)
+ domain = amdgpu_display_supported_domains(adev, rbo->flags);
+ else
+ domain = AMDGPU_GEM_DOMAIN_VRAM;
+
+ r = amdgpu_bo_pin(rbo, domain);
+ if (unlikely(r != 0)) {
+ if (r != -ERESTARTSYS)
+ DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
+ ttm_eu_backoff_reservation(&ticket, &list);
+ return r;
+ }
+
+ r = amdgpu_ttm_alloc_gart(&rbo->tbo);
+ if (unlikely(r != 0)) {
+ amdgpu_bo_unpin(rbo);
+ ttm_eu_backoff_reservation(&ticket, &list);
+ DRM_ERROR("%p bind failed\n", rbo);
+ return r;
+ }
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+
+ afb->address = amdgpu_bo_gpu_offset(rbo);
+
+ amdgpu_bo_ref(rbo);
+
+ return 0;
+}
+
+static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct amdgpu_bo *rbo;
+ int r;
+
+ if (!old_state->fb)
+ return;
+
+ rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
+ r = amdgpu_bo_reserve(rbo, false);
+ if (unlikely(r)) {
+ DRM_ERROR("failed to reserve rbo before unpin\n");
+ return;
+ }
+
+ amdgpu_bo_unpin(rbo);
+ amdgpu_bo_unreserve(rbo);
+ amdgpu_bo_unref(&rbo);
+}
+
+static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
+ .atomic_update = amdgpu_vkms_plane_atomic_update,
+ .atomic_check = amdgpu_vkms_plane_atomic_check,
+ .prepare_fb = amdgpu_vkms_prepare_fb,
+ .cleanup_fb = amdgpu_vkms_cleanup_fb,
+};
+
+static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
+ enum drm_plane_type type,
+ int index)
+{
+ struct drm_plane *plane;
+ int ret;
+
+ plane = kzalloc(sizeof(*plane), GFP_KERNEL);
+ if (!plane)
+ return ERR_PTR(-ENOMEM);
+
+ ret = drm_universal_plane_init(dev, plane, 1 << index,
+ &amdgpu_vkms_plane_funcs,
+ amdgpu_vkms_formats,
+ ARRAY_SIZE(amdgpu_vkms_formats),
+ NULL, type, NULL);
+ if (ret) {
+ kfree(plane);
+ return ERR_PTR(ret);
+ }
+
+ drm_plane_helper_add(plane, &amdgpu_vkms_primary_helper_funcs);
+
+ return plane;
+}
+
+int amdgpu_vkms_output_init(struct drm_device *dev,
+ struct amdgpu_vkms_output *output, int index)
+{
+ struct drm_connector *connector = &output->connector;
+ struct drm_encoder *encoder = &output->encoder;
+ struct drm_crtc *crtc = &output->crtc;
+ struct drm_plane *primary, *cursor = NULL;
+ int ret;
+
+ primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
+ if (IS_ERR(primary))
+ return PTR_ERR(primary);
+
+ ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
+ if (ret)
+ goto err_crtc;
+
+ ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
+ DRM_MODE_CONNECTOR_VIRTUAL);
+ if (ret) {
+ DRM_ERROR("Failed to init connector\n");
+ goto err_connector;
+ }
+
+ drm_connector_helper_add(connector, &amdgpu_vkms_conn_helper_funcs);
+
+ ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
+ if (ret) {
+ DRM_ERROR("Failed to init encoder\n");
+ goto err_encoder;
+ }
+ encoder->possible_crtcs = 1 << index;
+
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret) {
+ DRM_ERROR("Failed to attach connector to encoder\n");
+ goto err_attach;
+ }
+
+ drm_mode_config_reset(dev);
+
+ return 0;
+
+err_attach:
+ drm_encoder_cleanup(encoder);
+
+err_encoder:
+ drm_connector_cleanup(connector);
+
+err_connector:
+ drm_crtc_cleanup(crtc);
+
+err_crtc:
+ drm_plane_cleanup(primary);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
new file mode 100644
index 000000000000..5dab51fbecf3
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _AMDGPU_VKMS_H_
+#define _AMDGPU_VKMS_H_
+
+#define XRES_DEF 1024
+#define YRES_DEF 764
+
+#define XRES_MAX 16384
+#define YRES_MAX 16384
+
+#define drm_crtc_to_amdgpu_vkms_output(target) \
+ container_of(target, struct amdgpu_vkms_output, crtc)
+
+extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
+
+struct amdgpu_vkms_output {
+ struct drm_crtc crtc;
+ struct drm_encoder encoder;
+ struct drm_connector connector;
+ struct hrtimer vblank_hrtimer;
+ ktime_t period_ns;
+ struct drm_pending_vblank_event *event;
+};
+
+int amdgpu_vkms_output_init(struct drm_device *dev,
+ struct amdgpu_vkms_output *output, int index);
+
+#endif /* _AMDGPU_VKMS_H_ */
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 7e0d8c092c7e..642c77533157 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -22,6 +22,7 @@
*/
#include <drm/drm_vblank.h>
+#include <drm/drm_atomic_helper.h>
#include "amdgpu.h"
#include "amdgpu_pm.h"
@@ -40,6 +41,7 @@
#include "dce_virtual.h"
#include "ivsrcid/ivsrcid_vislands30.h"
#include "amdgpu_display.h"
+#include "amdgpu_vkms.h"
#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
@@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
.force = dce_virtual_force,
};
+const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
+ .fb_create = amdgpu_display_user_framebuffer_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
static int dce_virtual_sw_init(void *handle)
{
int r, i;
@@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
adev_to_drm(adev)->max_vblank_count = 0;
- adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
+ adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
- adev_to_drm(adev)->mode_config.max_width = 16384;
- adev_to_drm(adev)->mode_config.max_height = 16384;
+ adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
+ adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
@@ -399,15 +407,11 @@ static int dce_virtual_sw_init(void *handle)
if (r)
return r;
- adev_to_drm(adev)->mode_config.max_width = 16384;
- adev_to_drm(adev)->mode_config.max_height = 16384;
+ adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
/* allocate crtcs, encoders, connectors */
for (i = 0; i < adev->mode_info.num_crtc; i++) {
- r = dce_virtual_crtc_init(adev, i);
- if (r)
- return r;
- r = dce_virtual_connector_encoder_init(adev, i);
+ r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
if (r)
return r;
}
@@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
kfree(adev->mode_info.bios_hardcoded_edid);
+ kfree(adev->amdgpu_vkms_output);
drm_kms_helper_poll_fini(adev_to_drm(adev));
--
2.32.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-21 17:07 ` [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2) Ryan Taylor
@ 2021-07-23 14:31 ` Alex Deucher
2021-07-24 2:07 ` Chen, Guchun
0 siblings, 1 reply; 13+ messages in thread
From: Alex Deucher @ 2021-07-23 14:31 UTC (permalink / raw)
To: Ryan Taylor
Cc: kernel test robot, Daniel Vetter, Siqueira, Rodrigo,
amd-gfx list, Melissa Wen, Maling list - DRI developers
On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
>
> Modify the VKMS driver into an api that dce_virtual can use to create
> virtual displays that obey drm's atomic modesetting api.
>
> v2: Made local functions static.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411 +++++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 29 ++
> drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
> 7 files changed, 458 insertions(+), 11 deletions(-)
> create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index f089794bbdd5..30cbcd5ce1cc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -120,6 +120,7 @@ amdgpu-y += \
> amdgpu-y += \
> dce_v10_0.o \
> dce_v11_0.o \
> + amdgpu_vkms.o \
> dce_virtual.o
>
> # add GFX block
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 54cf647bd018..d0a2f2ed433d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -919,6 +919,7 @@ struct amdgpu_device {
>
> /* display */
> bool enable_virtual_display;
> + struct amdgpu_vkms_output *amdgpu_vkms_output;
> struct amdgpu_mode_info mode_info;
> /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
> struct work_struct hotplug_work;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index d0c935cf4f0f..1b016e5bc75f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> int ret, retry = 0;
> bool supports_atomic = false;
>
> - if (!amdgpu_virtual_display &&
> + if (amdgpu_virtual_display ||
> amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
> supports_atomic = true;
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index 09b048647523..5a143ca02cf9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
> }
>
> /* disable all the possible outputs/crtcs before entering KMS mode */
> - if (!amdgpu_device_has_dc_support(adev))
> + if (!amdgpu_device_has_dc_support(adev) && !amdgpu_virtual_display)
> drm_helper_disable_unused_functions(adev_to_drm(adev));
>
> drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> new file mode 100644
> index 000000000000..d5c1f1c58f5f
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> @@ -0,0 +1,411 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +#include <drm/drm_vblank.h>
> +
> +#include "amdgpu.h"
> +#include "amdgpu_vkms.h"
> +#include "amdgpu_display.h"
> +
> +/**
> + * DOC: amdgpu_vkms
> + *
> + * The amdgpu vkms interface provides a virtual KMS interface for several use
> + * cases: devices without display hardware, platforms where the actual display
> + * hardware is not useful (e.g., servers), SR-IOV virtual functions, device
> + * emulation/simulation, and device bring up prior to display hardware being
> + * usable. We previously emulated a legacy KMS interface, but there was a desire
> + * to move to the atomic KMS interface. The vkms driver did everything we
> + * needed, but we wanted KMS support natively in the driver without buffer
> + * sharing and the ability to support an instance of VKMS per device. We first
> + * looked at splitting vkms into a stub driver and a helper module that other
> + * drivers could use to implement a virtual display, but this strategy ended up
> + * being messy due to driver specific callbacks needed for buffer management.
> + * Ultimately, it proved easier to import the vkms code as it mostly used core
> + * drm helpers anyway.
> + */
> +
> +static const u32 amdgpu_vkms_formats[] = {
> + DRM_FORMAT_XRGB8888,
> +};
> +
> +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
> +{
> + struct amdgpu_vkms_output *output = container_of(timer,
> + struct amdgpu_vkms_output,
> + vblank_hrtimer);
> + struct drm_crtc *crtc = &output->crtc;
> + u64 ret_overrun;
> + bool ret;
> +
> + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
> + output->period_ns);
> + WARN_ON(ret_overrun != 1);
> +
> + ret = drm_crtc_handle_vblank(crtc);
> + if (!ret)
> + DRM_ERROR("amdgpu_vkms failure on handling vblank");
> +
> + return HRTIMER_RESTART;
> +}
> +
> +static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
> +{
> + struct drm_device *dev = crtc->dev;
> + unsigned int pipe = drm_crtc_index(crtc);
> + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> + struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
> +
> + drm_calc_timestamping_constants(crtc, &crtc->mode);
> +
> + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
> + out->period_ns = ktime_set(0, vblank->framedur_ns);
> + hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
> +
> + return 0;
> +}
> +
> +static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc)
> +{
> + struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
> +
> + hrtimer_cancel(&out->vblank_hrtimer);
> +}
> +
> +static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> + int *max_error,
> + ktime_t *vblank_time,
> + bool in_vblank_irq)
> +{
> + struct drm_device *dev = crtc->dev;
> + unsigned int pipe = crtc->index;
> + struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> +
> + if (!READ_ONCE(vblank->enabled)) {
> + *vblank_time = ktime_get();
> + return true;
> + }
> +
> + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
> +
> + if (WARN_ON(*vblank_time == vblank->time))
> + return true;
> +
> + /*
> + * To prevent races we roll the hrtimer forward before we do any
> + * interrupt processing - this is how real hw works (the interrupt is
> + * only generated after all the vblank registers are updated) and what
> + * the vblank core expects. Therefore we need to always correct the
> + * timestampe by one frame.
> + */
> + *vblank_time -= output->period_ns;
> +
> + return true;
> +}
> +
> +static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
> + .set_config = drm_atomic_helper_set_config,
> + .destroy = drm_crtc_cleanup,
> + .page_flip = drm_atomic_helper_page_flip,
> + .reset = drm_atomic_helper_crtc_reset,
> + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> + .enable_vblank = amdgpu_vkms_enable_vblank,
> + .disable_vblank = amdgpu_vkms_disable_vblank,
> + .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
> +};
> +
> +static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> + struct drm_atomic_state *state)
> +{
> + drm_crtc_vblank_on(crtc);
> +}
> +
> +static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> + struct drm_atomic_state *state)
> +{
> + drm_crtc_vblank_off(crtc);
> +}
> +
> +static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> + struct drm_atomic_state *state)
> +{
> + if (crtc->state->event) {
> + spin_lock(&crtc->dev->event_lock);
> +
> + if (drm_crtc_vblank_get(crtc) != 0)
> + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> + else
> + drm_crtc_arm_vblank_event(crtc, crtc->state->event);
> +
> + spin_unlock(&crtc->dev->event_lock);
> +
> + crtc->state->event = NULL;
> + }
> +}
> +
> +static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> + .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
> + .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
> + .atomic_disable = amdgpu_vkms_crtc_atomic_disable,
> +};
> +
> +static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> + struct drm_plane *primary, struct drm_plane *cursor)
> +{
> + int ret;
> +
> + ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
> + &amdgpu_vkms_crtc_funcs, NULL);
> + if (ret) {
> + DRM_ERROR("Failed to init CRTC\n");
> + return ret;
> + }
> +
> + drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
> +
> + return ret;
> +}
> +
> +static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .destroy = drm_connector_cleanup,
> + .reset = drm_atomic_helper_connector_reset,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
> +{
> + int count;
> +
> + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> +
> + return count;
> +}
> +
> +static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> + .get_modes = amdgpu_vkms_conn_get_modes,
> +};
> +
> +static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
> + .update_plane = drm_atomic_helper_update_plane,
> + .disable_plane = drm_atomic_helper_disable_plane,
> + .destroy = drm_plane_cleanup,
> + .reset = drm_atomic_helper_plane_reset,
> + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> +};
> +
> +static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
> + struct drm_plane_state *old_state)
> +{
> + return;
> +}
> +
> +static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
> + struct drm_plane_state *state)
> +{
> + struct drm_crtc_state *crtc_state;
> + bool can_position = false;
> + int ret;
> +
> + if (!state->fb || WARN_ON(!state->crtc))
> + return 0;
> +
> + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> + if (IS_ERR(crtc_state))
> + return PTR_ERR(crtc_state);
> +
> + ret = drm_atomic_helper_check_plane_state(state, crtc_state,
> + DRM_PLANE_HELPER_NO_SCALING,
> + DRM_PLANE_HELPER_NO_SCALING,
> + can_position, true);
> + if (ret != 0)
> + return ret;
> +
> + /* for now primary plane must be visible and full screen */
> + if (!state->visible && !can_position)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
> + struct drm_plane_state *new_state)
> +{
> + struct amdgpu_framebuffer *afb;
> + struct drm_gem_object *obj;
> + struct amdgpu_device *adev;
> + struct amdgpu_bo *rbo;
> + struct list_head list;
> + struct ttm_validate_buffer tv;
> + struct ww_acquire_ctx ticket;
> + uint32_t domain;
> + int r;
> +
> + if (!new_state->fb) {
> + DRM_DEBUG_KMS("No FB bound\n");
> + return 0;
> + }
> + afb = to_amdgpu_framebuffer(new_state->fb);
> + obj = new_state->fb->obj[0];
> + rbo = gem_to_amdgpu_bo(obj);
> + adev = amdgpu_ttm_adev(rbo->tbo.bdev);
> + INIT_LIST_HEAD(&list);
> +
> + tv.bo = &rbo->tbo;
> + tv.num_shared = 1;
> + list_add(&tv.head, &list);
> +
> + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
> + if (r) {
> + dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
> + return r;
> + }
> +
> + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> + domain = amdgpu_display_supported_domains(adev, rbo->flags);
> + else
> + domain = AMDGPU_GEM_DOMAIN_VRAM;
> +
> + r = amdgpu_bo_pin(rbo, domain);
> + if (unlikely(r != 0)) {
> + if (r != -ERESTARTSYS)
> + DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
> + ttm_eu_backoff_reservation(&ticket, &list);
> + return r;
> + }
> +
> + r = amdgpu_ttm_alloc_gart(&rbo->tbo);
> + if (unlikely(r != 0)) {
> + amdgpu_bo_unpin(rbo);
> + ttm_eu_backoff_reservation(&ticket, &list);
> + DRM_ERROR("%p bind failed\n", rbo);
> + return r;
> + }
> +
> + ttm_eu_backoff_reservation(&ticket, &list);
> +
> + afb->address = amdgpu_bo_gpu_offset(rbo);
> +
> + amdgpu_bo_ref(rbo);
> +
> + return 0;
> +}
> +
> +static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
> + struct drm_plane_state *old_state)
> +{
> + struct amdgpu_bo *rbo;
> + int r;
> +
> + if (!old_state->fb)
> + return;
> +
> + rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
> + r = amdgpu_bo_reserve(rbo, false);
> + if (unlikely(r)) {
> + DRM_ERROR("failed to reserve rbo before unpin\n");
> + return;
> + }
> +
> + amdgpu_bo_unpin(rbo);
> + amdgpu_bo_unreserve(rbo);
> + amdgpu_bo_unref(&rbo);
> +}
> +
> +static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
> + .atomic_update = amdgpu_vkms_plane_atomic_update,
> + .atomic_check = amdgpu_vkms_plane_atomic_check,
> + .prepare_fb = amdgpu_vkms_prepare_fb,
> + .cleanup_fb = amdgpu_vkms_cleanup_fb,
> +};
> +
> +static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
> + enum drm_plane_type type,
> + int index)
> +{
> + struct drm_plane *plane;
> + int ret;
> +
> + plane = kzalloc(sizeof(*plane), GFP_KERNEL);
> + if (!plane)
> + return ERR_PTR(-ENOMEM);
> +
> + ret = drm_universal_plane_init(dev, plane, 1 << index,
> + &amdgpu_vkms_plane_funcs,
> + amdgpu_vkms_formats,
> + ARRAY_SIZE(amdgpu_vkms_formats),
> + NULL, type, NULL);
> + if (ret) {
> + kfree(plane);
> + return ERR_PTR(ret);
> + }
> +
> + drm_plane_helper_add(plane, &amdgpu_vkms_primary_helper_funcs);
> +
> + return plane;
> +}
> +
> +int amdgpu_vkms_output_init(struct drm_device *dev,
> + struct amdgpu_vkms_output *output, int index)
> +{
> + struct drm_connector *connector = &output->connector;
> + struct drm_encoder *encoder = &output->encoder;
> + struct drm_crtc *crtc = &output->crtc;
> + struct drm_plane *primary, *cursor = NULL;
> + int ret;
> +
> + primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
> + if (IS_ERR(primary))
> + return PTR_ERR(primary);
> +
> + ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
> + if (ret)
> + goto err_crtc;
> +
> + ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
> + DRM_MODE_CONNECTOR_VIRTUAL);
> + if (ret) {
> + DRM_ERROR("Failed to init connector\n");
> + goto err_connector;
> + }
> +
> + drm_connector_helper_add(connector, &amdgpu_vkms_conn_helper_funcs);
> +
> + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
> + if (ret) {
> + DRM_ERROR("Failed to init encoder\n");
> + goto err_encoder;
> + }
> + encoder->possible_crtcs = 1 << index;
> +
> + ret = drm_connector_attach_encoder(connector, encoder);
> + if (ret) {
> + DRM_ERROR("Failed to attach connector to encoder\n");
> + goto err_attach;
> + }
> +
> + drm_mode_config_reset(dev);
> +
> + return 0;
> +
> +err_attach:
> + drm_encoder_cleanup(encoder);
> +
> +err_encoder:
> + drm_connector_cleanup(connector);
> +
> +err_connector:
> + drm_crtc_cleanup(crtc);
> +
> +err_crtc:
> + drm_plane_cleanup(primary);
> +
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> new file mode 100644
> index 000000000000..5dab51fbecf3
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +#ifndef _AMDGPU_VKMS_H_
> +#define _AMDGPU_VKMS_H_
> +
> +#define XRES_DEF 1024
> +#define YRES_DEF 764
Squash in the 768 fix here.
> +
> +#define XRES_MAX 16384
> +#define YRES_MAX 16384
> +
> +#define drm_crtc_to_amdgpu_vkms_output(target) \
> + container_of(target, struct amdgpu_vkms_output, crtc)
> +
> +extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
> +
> +struct amdgpu_vkms_output {
> + struct drm_crtc crtc;
> + struct drm_encoder encoder;
> + struct drm_connector connector;
> + struct hrtimer vblank_hrtimer;
> + ktime_t period_ns;
> + struct drm_pending_vblank_event *event;
> +};
> +
> +int amdgpu_vkms_output_init(struct drm_device *dev,
> + struct amdgpu_vkms_output *output, int index);
> +
> +#endif /* _AMDGPU_VKMS_H_ */
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> index 7e0d8c092c7e..642c77533157 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> @@ -22,6 +22,7 @@
> */
>
> #include <drm/drm_vblank.h>
> +#include <drm/drm_atomic_helper.h>
>
> #include "amdgpu.h"
> #include "amdgpu_pm.h"
> @@ -40,6 +41,7 @@
> #include "dce_virtual.h"
> #include "ivsrcid/ivsrcid_vislands30.h"
> #include "amdgpu_display.h"
> +#include "amdgpu_vkms.h"
>
> #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
>
> @@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> .force = dce_virtual_force,
> };
>
> +const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> + .fb_create = amdgpu_display_user_framebuffer_create,
> + .atomic_check = drm_atomic_helper_check,
> + .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> static int dce_virtual_sw_init(void *handle)
> {
> int r, i;
> @@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
>
> adev_to_drm(adev)->max_vblank_count = 0;
>
> - adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
> + adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
>
> - adev_to_drm(adev)->mode_config.max_width = 16384;
> - adev_to_drm(adev)->mode_config.max_height = 16384;
> + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
>
> adev_to_drm(adev)->mode_config.preferred_depth = 24;
> adev_to_drm(adev)->mode_config.prefer_shadow = 1;
> @@ -399,15 +407,11 @@ static int dce_virtual_sw_init(void *handle)
> if (r)
> return r;
>
> - adev_to_drm(adev)->mode_config.max_width = 16384;
> - adev_to_drm(adev)->mode_config.max_height = 16384;
> + adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
You can use kcalloc here.
>
> /* allocate crtcs, encoders, connectors */
> for (i = 0; i < adev->mode_info.num_crtc; i++) {
> - r = dce_virtual_crtc_init(adev, i);
> - if (r)
> - return r;
> - r = dce_virtual_connector_encoder_init(adev, i);
> + r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
> if (r)
> return r;
> }
> @@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
> hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
>
> kfree(adev->mode_info.bios_hardcoded_edid);
> + kfree(adev->amdgpu_vkms_output);
>
> drm_kms_helper_poll_fini(adev_to_drm(adev));
>
> --
> 2.32.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-23 14:31 ` Alex Deucher
@ 2021-07-24 2:07 ` Chen, Guchun
2021-07-26 16:21 ` Alex Deucher
0 siblings, 1 reply; 13+ messages in thread
From: Chen, Guchun @ 2021-07-24 2:07 UTC (permalink / raw)
To: Alex Deucher, Taylor, Ryan
Cc: kernel test robot, Daniel Vetter, Siqueira, Rodrigo,
Maling list - DRI developers, Melissa Wen, amd-gfx list
[Public]
Look copy right statement is missed in both amdgpu_vkms.c and amdgpu_vkms.h.
Regards,
Guchun
-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
Sent: Friday, July 23, 2021 10:32 PM
To: Taylor, Ryan <Ryan.Taylor@amd.com>
Cc: kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
>
> Modify the VKMS driver into an api that dce_virtual can use to create
> virtual displays that obey drm's atomic modesetting api.
>
> v2: Made local functions static.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411
> +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h |
> 29 ++ drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
> 7 files changed, 458 insertions(+), 11 deletions(-) create mode
> 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile
> b/drivers/gpu/drm/amd/amdgpu/Makefile
> index f089794bbdd5..30cbcd5ce1cc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -120,6 +120,7 @@ amdgpu-y += \
> amdgpu-y += \
> dce_v10_0.o \
> dce_v11_0.o \
> + amdgpu_vkms.o \
> dce_virtual.o
>
> # add GFX block
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 54cf647bd018..d0a2f2ed433d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -919,6 +919,7 @@ struct amdgpu_device {
>
> /* display */
> bool enable_virtual_display;
> + struct amdgpu_vkms_output *amdgpu_vkms_output;
> struct amdgpu_mode_info mode_info;
> /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
> struct work_struct hotplug_work;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index d0c935cf4f0f..1b016e5bc75f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> int ret, retry = 0;
> bool supports_atomic = false;
>
> - if (!amdgpu_virtual_display &&
> + if (amdgpu_virtual_display ||
> amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
> supports_atomic = true;
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index 09b048647523..5a143ca02cf9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
> }
>
> /* disable all the possible outputs/crtcs before entering KMS mode */
> - if (!amdgpu_device_has_dc_support(adev))
> + if (!amdgpu_device_has_dc_support(adev) &&
> + !amdgpu_virtual_display)
>
> drm_helper_disable_unused_functions(adev_to_drm(adev));
>
> drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); diff
> --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> new file mode 100644
> index 000000000000..d5c1f1c58f5f
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> @@ -0,0 +1,411 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_simple_kms_helper.h> #include <drm/drm_vblank.h>
> +
> +#include "amdgpu.h"
> +#include "amdgpu_vkms.h"
> +#include "amdgpu_display.h"
> +
> +/**
> + * DOC: amdgpu_vkms
> + *
> + * The amdgpu vkms interface provides a virtual KMS interface for
> +several use
> + * cases: devices without display hardware, platforms where the
> +actual display
> + * hardware is not useful (e.g., servers), SR-IOV virtual functions,
> +device
> + * emulation/simulation, and device bring up prior to display
> +hardware being
> + * usable. We previously emulated a legacy KMS interface, but there
> +was a desire
> + * to move to the atomic KMS interface. The vkms driver did
> +everything we
> + * needed, but we wanted KMS support natively in the driver without
> +buffer
> + * sharing and the ability to support an instance of VKMS per device.
> +We first
> + * looked at splitting vkms into a stub driver and a helper module
> +that other
> + * drivers could use to implement a virtual display, but this
> +strategy ended up
> + * being messy due to driver specific callbacks needed for buffer management.
> + * Ultimately, it proved easier to import the vkms code as it mostly
> +used core
> + * drm helpers anyway.
> + */
> +
> +static const u32 amdgpu_vkms_formats[] = {
> + DRM_FORMAT_XRGB8888,
> +};
> +
> +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct
> +hrtimer *timer) {
> + struct amdgpu_vkms_output *output = container_of(timer,
> + struct amdgpu_vkms_output,
> + vblank_hrtimer);
> + struct drm_crtc *crtc = &output->crtc;
> + u64 ret_overrun;
> + bool ret;
> +
> + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
> + output->period_ns);
> + WARN_ON(ret_overrun != 1);
> +
> + ret = drm_crtc_handle_vblank(crtc);
> + if (!ret)
> + DRM_ERROR("amdgpu_vkms failure on handling vblank");
> +
> + return HRTIMER_RESTART;
> +}
> +
> +static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc) {
> + struct drm_device *dev = crtc->dev;
> + unsigned int pipe = drm_crtc_index(crtc);
> + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> + struct amdgpu_vkms_output *out =
> +drm_crtc_to_amdgpu_vkms_output(crtc);
> +
> + drm_calc_timestamping_constants(crtc, &crtc->mode);
> +
> + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
> + out->period_ns = ktime_set(0, vblank->framedur_ns);
> + hrtimer_start(&out->vblank_hrtimer, out->period_ns,
> + HRTIMER_MODE_REL);
> +
> + return 0;
> +}
> +
> +static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) {
> + struct amdgpu_vkms_output *out =
> +drm_crtc_to_amdgpu_vkms_output(crtc);
> +
> + hrtimer_cancel(&out->vblank_hrtimer);
> +}
> +
> +static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> + int *max_error,
> + ktime_t *vblank_time,
> + bool in_vblank_irq) {
> + struct drm_device *dev = crtc->dev;
> + unsigned int pipe = crtc->index;
> + struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> +
> + if (!READ_ONCE(vblank->enabled)) {
> + *vblank_time = ktime_get();
> + return true;
> + }
> +
> + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
> +
> + if (WARN_ON(*vblank_time == vblank->time))
> + return true;
> +
> + /*
> + * To prevent races we roll the hrtimer forward before we do any
> + * interrupt processing - this is how real hw works (the interrupt is
> + * only generated after all the vblank registers are updated) and what
> + * the vblank core expects. Therefore we need to always correct the
> + * timestampe by one frame.
> + */
> + *vblank_time -= output->period_ns;
> +
> + return true;
> +}
> +
> +static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
> + .set_config = drm_atomic_helper_set_config,
> + .destroy = drm_crtc_cleanup,
> + .page_flip = drm_atomic_helper_page_flip,
> + .reset = drm_atomic_helper_crtc_reset,
> + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> + .enable_vblank = amdgpu_vkms_enable_vblank,
> + .disable_vblank = amdgpu_vkms_disable_vblank,
> + .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
> +};
> +
> +static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> + struct drm_atomic_state
> +*state) {
> + drm_crtc_vblank_on(crtc);
> +}
> +
> +static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> + struct drm_atomic_state
> +*state) {
> + drm_crtc_vblank_off(crtc);
> +}
> +
> +static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> + struct drm_atomic_state
> +*state) {
> + if (crtc->state->event) {
> + spin_lock(&crtc->dev->event_lock);
> +
> + if (drm_crtc_vblank_get(crtc) != 0)
> + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> + else
> + drm_crtc_arm_vblank_event(crtc,
> + crtc->state->event);
> +
> + spin_unlock(&crtc->dev->event_lock);
> +
> + crtc->state->event = NULL;
> + }
> +}
> +
> +static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> + .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
> + .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
> + .atomic_disable = amdgpu_vkms_crtc_atomic_disable, };
> +
> +static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> + struct drm_plane *primary, struct drm_plane
> +*cursor) {
> + int ret;
> +
> + ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
> + &amdgpu_vkms_crtc_funcs, NULL);
> + if (ret) {
> + DRM_ERROR("Failed to init CRTC\n");
> + return ret;
> + }
> +
> + drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
> +
> + return ret;
> +}
> +
> +static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .destroy = drm_connector_cleanup,
> + .reset = drm_atomic_helper_connector_reset,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state =
> +drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static int amdgpu_vkms_conn_get_modes(struct drm_connector
> +*connector) {
> + int count;
> +
> + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> +
> + return count;
> +}
> +
> +static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> + .get_modes = amdgpu_vkms_conn_get_modes,
> +};
> +
> +static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
> + .update_plane = drm_atomic_helper_update_plane,
> + .disable_plane = drm_atomic_helper_disable_plane,
> + .destroy = drm_plane_cleanup,
> + .reset = drm_atomic_helper_plane_reset,
> + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> +};
> +
> +static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
> + struct drm_plane_state
> +*old_state) {
> + return;
> +}
> +
> +static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
> + struct drm_plane_state
> +*state) {
> + struct drm_crtc_state *crtc_state;
> + bool can_position = false;
> + int ret;
> +
> + if (!state->fb || WARN_ON(!state->crtc))
> + return 0;
> +
> + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> + if (IS_ERR(crtc_state))
> + return PTR_ERR(crtc_state);
> +
> + ret = drm_atomic_helper_check_plane_state(state, crtc_state,
> + DRM_PLANE_HELPER_NO_SCALING,
> + DRM_PLANE_HELPER_NO_SCALING,
> + can_position, true);
> + if (ret != 0)
> + return ret;
> +
> + /* for now primary plane must be visible and full screen */
> + if (!state->visible && !can_position)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
> + struct drm_plane_state *new_state) {
> + struct amdgpu_framebuffer *afb;
> + struct drm_gem_object *obj;
> + struct amdgpu_device *adev;
> + struct amdgpu_bo *rbo;
> + struct list_head list;
> + struct ttm_validate_buffer tv;
> + struct ww_acquire_ctx ticket;
> + uint32_t domain;
> + int r;
> +
> + if (!new_state->fb) {
> + DRM_DEBUG_KMS("No FB bound\n");
> + return 0;
> + }
> + afb = to_amdgpu_framebuffer(new_state->fb);
> + obj = new_state->fb->obj[0];
> + rbo = gem_to_amdgpu_bo(obj);
> + adev = amdgpu_ttm_adev(rbo->tbo.bdev);
> + INIT_LIST_HEAD(&list);
> +
> + tv.bo = &rbo->tbo;
> + tv.num_shared = 1;
> + list_add(&tv.head, &list);
> +
> + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
> + if (r) {
> + dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
> + return r;
> + }
> +
> + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> + domain = amdgpu_display_supported_domains(adev, rbo->flags);
> + else
> + domain = AMDGPU_GEM_DOMAIN_VRAM;
> +
> + r = amdgpu_bo_pin(rbo, domain);
> + if (unlikely(r != 0)) {
> + if (r != -ERESTARTSYS)
> + DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
> + ttm_eu_backoff_reservation(&ticket, &list);
> + return r;
> + }
> +
> + r = amdgpu_ttm_alloc_gart(&rbo->tbo);
> + if (unlikely(r != 0)) {
> + amdgpu_bo_unpin(rbo);
> + ttm_eu_backoff_reservation(&ticket, &list);
> + DRM_ERROR("%p bind failed\n", rbo);
> + return r;
> + }
> +
> + ttm_eu_backoff_reservation(&ticket, &list);
> +
> + afb->address = amdgpu_bo_gpu_offset(rbo);
> +
> + amdgpu_bo_ref(rbo);
> +
> + return 0;
> +}
> +
> +static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
> + struct drm_plane_state *old_state)
> +{
> + struct amdgpu_bo *rbo;
> + int r;
> +
> + if (!old_state->fb)
> + return;
> +
> + rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
> + r = amdgpu_bo_reserve(rbo, false);
> + if (unlikely(r)) {
> + DRM_ERROR("failed to reserve rbo before unpin\n");
> + return;
> + }
> +
> + amdgpu_bo_unpin(rbo);
> + amdgpu_bo_unreserve(rbo);
> + amdgpu_bo_unref(&rbo);
> +}
> +
> +static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
> + .atomic_update = amdgpu_vkms_plane_atomic_update,
> + .atomic_check = amdgpu_vkms_plane_atomic_check,
> + .prepare_fb = amdgpu_vkms_prepare_fb,
> + .cleanup_fb = amdgpu_vkms_cleanup_fb,
> +};
> +
> +static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
> + enum drm_plane_type type,
> + int index) {
> + struct drm_plane *plane;
> + int ret;
> +
> + plane = kzalloc(sizeof(*plane), GFP_KERNEL);
> + if (!plane)
> + return ERR_PTR(-ENOMEM);
> +
> + ret = drm_universal_plane_init(dev, plane, 1 << index,
> + &amdgpu_vkms_plane_funcs,
> + amdgpu_vkms_formats,
> + ARRAY_SIZE(amdgpu_vkms_formats),
> + NULL, type, NULL);
> + if (ret) {
> + kfree(plane);
> + return ERR_PTR(ret);
> + }
> +
> + drm_plane_helper_add(plane,
> + &amdgpu_vkms_primary_helper_funcs);
> +
> + return plane;
> +}
> +
> +int amdgpu_vkms_output_init(struct drm_device *dev,
> + struct amdgpu_vkms_output *output, int
> +index) {
> + struct drm_connector *connector = &output->connector;
> + struct drm_encoder *encoder = &output->encoder;
> + struct drm_crtc *crtc = &output->crtc;
> + struct drm_plane *primary, *cursor = NULL;
> + int ret;
> +
> + primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
> + if (IS_ERR(primary))
> + return PTR_ERR(primary);
> +
> + ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
> + if (ret)
> + goto err_crtc;
> +
> + ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
> + DRM_MODE_CONNECTOR_VIRTUAL);
> + if (ret) {
> + DRM_ERROR("Failed to init connector\n");
> + goto err_connector;
> + }
> +
> + drm_connector_helper_add(connector,
> + &amdgpu_vkms_conn_helper_funcs);
> +
> + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
> + if (ret) {
> + DRM_ERROR("Failed to init encoder\n");
> + goto err_encoder;
> + }
> + encoder->possible_crtcs = 1 << index;
> +
> + ret = drm_connector_attach_encoder(connector, encoder);
> + if (ret) {
> + DRM_ERROR("Failed to attach connector to encoder\n");
> + goto err_attach;
> + }
> +
> + drm_mode_config_reset(dev);
> +
> + return 0;
> +
> +err_attach:
> + drm_encoder_cleanup(encoder);
> +
> +err_encoder:
> + drm_connector_cleanup(connector);
> +
> +err_connector:
> + drm_crtc_cleanup(crtc);
> +
> +err_crtc:
> + drm_plane_cleanup(primary);
> +
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> new file mode 100644
> index 000000000000..5dab51fbecf3
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +#ifndef _AMDGPU_VKMS_H_
> +#define _AMDGPU_VKMS_H_
> +
> +#define XRES_DEF 1024
> +#define YRES_DEF 764
Squash in the 768 fix here.
> +
> +#define XRES_MAX 16384
> +#define YRES_MAX 16384
> +
> +#define drm_crtc_to_amdgpu_vkms_output(target) \
> + container_of(target, struct amdgpu_vkms_output, crtc)
> +
> +extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
> +
> +struct amdgpu_vkms_output {
> + struct drm_crtc crtc;
> + struct drm_encoder encoder;
> + struct drm_connector connector;
> + struct hrtimer vblank_hrtimer;
> + ktime_t period_ns;
> + struct drm_pending_vblank_event *event; };
> +
> +int amdgpu_vkms_output_init(struct drm_device *dev,
> + struct amdgpu_vkms_output *output, int
> +index);
> +
> +#endif /* _AMDGPU_VKMS_H_ */
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> index 7e0d8c092c7e..642c77533157 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> @@ -22,6 +22,7 @@
> */
>
> #include <drm/drm_vblank.h>
> +#include <drm/drm_atomic_helper.h>
>
> #include "amdgpu.h"
> #include "amdgpu_pm.h"
> @@ -40,6 +41,7 @@
> #include "dce_virtual.h"
> #include "ivsrcid/ivsrcid_vislands30.h"
> #include "amdgpu_display.h"
> +#include "amdgpu_vkms.h"
>
> #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
>
> @@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> .force = dce_virtual_force,
> };
>
> +const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> + .fb_create = amdgpu_display_user_framebuffer_create,
> + .atomic_check = drm_atomic_helper_check,
> + .atomic_commit = drm_atomic_helper_commit, };
> +
> static int dce_virtual_sw_init(void *handle) {
> int r, i;
> @@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
>
> adev_to_drm(adev)->max_vblank_count = 0;
>
> - adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
> + adev_to_drm(adev)->mode_config.funcs =
> + &dce_virtual_mode_funcs;
>
> - adev_to_drm(adev)->mode_config.max_width = 16384;
> - adev_to_drm(adev)->mode_config.max_height = 16384;
> + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
>
> adev_to_drm(adev)->mode_config.preferred_depth = 24;
> adev_to_drm(adev)->mode_config.prefer_shadow = 1; @@ -399,15
> +407,11 @@ static int dce_virtual_sw_init(void *handle)
> if (r)
> return r;
>
> - adev_to_drm(adev)->mode_config.max_width = 16384;
> - adev_to_drm(adev)->mode_config.max_height = 16384;
> + adev->amdgpu_vkms_output = kzalloc(sizeof(struct
> + amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
You can use kcalloc here.
>
> /* allocate crtcs, encoders, connectors */
> for (i = 0; i < adev->mode_info.num_crtc; i++) {
> - r = dce_virtual_crtc_init(adev, i);
> - if (r)
> - return r;
> - r = dce_virtual_connector_encoder_init(adev, i);
> + r = amdgpu_vkms_output_init(adev_to_drm(adev),
> + &adev->amdgpu_vkms_output[i], i);
> if (r)
> return r;
> }
> @@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
>
> hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
>
> kfree(adev->mode_info.bios_hardcoded_edid);
> + kfree(adev->amdgpu_vkms_output);
>
> drm_kms_helper_poll_fini(adev_to_drm(adev));
>
> --
> 2.32.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flist
> s.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cgu
> chun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884
> e608e11a82d994e183d%7C0%7C0%7C637626475284480052%7CUnknown%7CTWFpbGZsb
> 3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> 7C1000&sdata=0bbTKflaP2RPk%2BpboaNNiwffbEw1pW0zkqcxzPWjzmI%3D&
> reserved=0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cguchun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637626475284490043%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=VQ1liQG9OOsBA3NtjS93WNu6NhlLQ0fXQRbLwLmz95g%3D&reserved=0
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-24 2:07 ` Chen, Guchun
@ 2021-07-26 16:21 ` Alex Deucher
2021-07-26 16:39 ` Taylor, Ryan
0 siblings, 1 reply; 13+ messages in thread
From: Alex Deucher @ 2021-07-26 16:21 UTC (permalink / raw)
To: Chen, Guchun
Cc: kernel test robot, Daniel Vetter, Siqueira, Rodrigo, Taylor,
Ryan, amd-gfx list, Melissa Wen, Maling list - DRI developers
On Fri, Jul 23, 2021 at 10:07 PM Chen, Guchun <Guchun.Chen@amd.com> wrote:
>
> [Public]
>
> Look copy right statement is missed in both amdgpu_vkms.c and amdgpu_vkms.h.
It's there, it just uses the newer SPDX license identifier.
Alex
>
> Regards,
> Guchun
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
> Sent: Friday, July 23, 2021 10:32 PM
> To: Taylor, Ryan <Ryan.Taylor@amd.com>
> Cc: kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
> Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
>
> On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
> >
> > Modify the VKMS driver into an api that dce_virtual can use to create
> > virtual displays that obey drm's atomic modesetting api.
> >
> > v2: Made local functions static.
> >
> > Reported-by: kernel test robot <lkp@intel.com>
> > Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> > ---
> > drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
> > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
> > drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
> > drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411
> > +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h |
> > 29 ++ drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
> > 7 files changed, 458 insertions(+), 11 deletions(-) create mode
> > 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile
> > b/drivers/gpu/drm/amd/amdgpu/Makefile
> > index f089794bbdd5..30cbcd5ce1cc 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> > @@ -120,6 +120,7 @@ amdgpu-y += \
> > amdgpu-y += \
> > dce_v10_0.o \
> > dce_v11_0.o \
> > + amdgpu_vkms.o \
> > dce_virtual.o
> >
> > # add GFX block
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > index 54cf647bd018..d0a2f2ed433d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > @@ -919,6 +919,7 @@ struct amdgpu_device {
> >
> > /* display */
> > bool enable_virtual_display;
> > + struct amdgpu_vkms_output *amdgpu_vkms_output;
> > struct amdgpu_mode_info mode_info;
> > /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
> > struct work_struct hotplug_work;
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > index d0c935cf4f0f..1b016e5bc75f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > @@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> > int ret, retry = 0;
> > bool supports_atomic = false;
> >
> > - if (!amdgpu_virtual_display &&
> > + if (amdgpu_virtual_display ||
> > amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
> > supports_atomic = true;
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > index 09b048647523..5a143ca02cf9 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
> > }
> >
> > /* disable all the possible outputs/crtcs before entering KMS mode */
> > - if (!amdgpu_device_has_dc_support(adev))
> > + if (!amdgpu_device_has_dc_support(adev) &&
> > + !amdgpu_virtual_display)
> >
> > drm_helper_disable_unused_functions(adev_to_drm(adev));
> >
> > drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); diff
> > --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > new file mode 100644
> > index 000000000000..d5c1f1c58f5f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > @@ -0,0 +1,411 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_simple_kms_helper.h> #include <drm/drm_vblank.h>
> > +
> > +#include "amdgpu.h"
> > +#include "amdgpu_vkms.h"
> > +#include "amdgpu_display.h"
> > +
> > +/**
> > + * DOC: amdgpu_vkms
> > + *
> > + * The amdgpu vkms interface provides a virtual KMS interface for
> > +several use
> > + * cases: devices without display hardware, platforms where the
> > +actual display
> > + * hardware is not useful (e.g., servers), SR-IOV virtual functions,
> > +device
> > + * emulation/simulation, and device bring up prior to display
> > +hardware being
> > + * usable. We previously emulated a legacy KMS interface, but there
> > +was a desire
> > + * to move to the atomic KMS interface. The vkms driver did
> > +everything we
> > + * needed, but we wanted KMS support natively in the driver without
> > +buffer
> > + * sharing and the ability to support an instance of VKMS per device.
> > +We first
> > + * looked at splitting vkms into a stub driver and a helper module
> > +that other
> > + * drivers could use to implement a virtual display, but this
> > +strategy ended up
> > + * being messy due to driver specific callbacks needed for buffer management.
> > + * Ultimately, it proved easier to import the vkms code as it mostly
> > +used core
> > + * drm helpers anyway.
> > + */
> > +
> > +static const u32 amdgpu_vkms_formats[] = {
> > + DRM_FORMAT_XRGB8888,
> > +};
> > +
> > +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct
> > +hrtimer *timer) {
> > + struct amdgpu_vkms_output *output = container_of(timer,
> > + struct amdgpu_vkms_output,
> > + vblank_hrtimer);
> > + struct drm_crtc *crtc = &output->crtc;
> > + u64 ret_overrun;
> > + bool ret;
> > +
> > + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
> > + output->period_ns);
> > + WARN_ON(ret_overrun != 1);
> > +
> > + ret = drm_crtc_handle_vblank(crtc);
> > + if (!ret)
> > + DRM_ERROR("amdgpu_vkms failure on handling vblank");
> > +
> > + return HRTIMER_RESTART;
> > +}
> > +
> > +static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc) {
> > + struct drm_device *dev = crtc->dev;
> > + unsigned int pipe = drm_crtc_index(crtc);
> > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > + struct amdgpu_vkms_output *out =
> > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > +
> > + drm_calc_timestamping_constants(crtc, &crtc->mode);
> > +
> > + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> > + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
> > + out->period_ns = ktime_set(0, vblank->framedur_ns);
> > + hrtimer_start(&out->vblank_hrtimer, out->period_ns,
> > + HRTIMER_MODE_REL);
> > +
> > + return 0;
> > +}
> > +
> > +static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) {
> > + struct amdgpu_vkms_output *out =
> > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > +
> > + hrtimer_cancel(&out->vblank_hrtimer);
> > +}
> > +
> > +static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> > + int *max_error,
> > + ktime_t *vblank_time,
> > + bool in_vblank_irq) {
> > + struct drm_device *dev = crtc->dev;
> > + unsigned int pipe = crtc->index;
> > + struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > +
> > + if (!READ_ONCE(vblank->enabled)) {
> > + *vblank_time = ktime_get();
> > + return true;
> > + }
> > +
> > + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
> > +
> > + if (WARN_ON(*vblank_time == vblank->time))
> > + return true;
> > +
> > + /*
> > + * To prevent races we roll the hrtimer forward before we do any
> > + * interrupt processing - this is how real hw works (the interrupt is
> > + * only generated after all the vblank registers are updated) and what
> > + * the vblank core expects. Therefore we need to always correct the
> > + * timestampe by one frame.
> > + */
> > + *vblank_time -= output->period_ns;
> > +
> > + return true;
> > +}
> > +
> > +static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
> > + .set_config = drm_atomic_helper_set_config,
> > + .destroy = drm_crtc_cleanup,
> > + .page_flip = drm_atomic_helper_page_flip,
> > + .reset = drm_atomic_helper_crtc_reset,
> > + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> > + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> > + .enable_vblank = amdgpu_vkms_enable_vblank,
> > + .disable_vblank = amdgpu_vkms_disable_vblank,
> > + .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
> > +};
> > +
> > +static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> > + struct drm_atomic_state
> > +*state) {
> > + drm_crtc_vblank_on(crtc);
> > +}
> > +
> > +static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> > + struct drm_atomic_state
> > +*state) {
> > + drm_crtc_vblank_off(crtc);
> > +}
> > +
> > +static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> > + struct drm_atomic_state
> > +*state) {
> > + if (crtc->state->event) {
> > + spin_lock(&crtc->dev->event_lock);
> > +
> > + if (drm_crtc_vblank_get(crtc) != 0)
> > + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> > + else
> > + drm_crtc_arm_vblank_event(crtc,
> > + crtc->state->event);
> > +
> > + spin_unlock(&crtc->dev->event_lock);
> > +
> > + crtc->state->event = NULL;
> > + }
> > +}
> > +
> > +static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> > + .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
> > + .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
> > + .atomic_disable = amdgpu_vkms_crtc_atomic_disable, };
> > +
> > +static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> > + struct drm_plane *primary, struct drm_plane
> > +*cursor) {
> > + int ret;
> > +
> > + ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
> > + &amdgpu_vkms_crtc_funcs, NULL);
> > + if (ret) {
> > + DRM_ERROR("Failed to init CRTC\n");
> > + return ret;
> > + }
> > +
> > + drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
> > +
> > + return ret;
> > +}
> > +
> > +static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
> > + .fill_modes = drm_helper_probe_single_connector_modes,
> > + .destroy = drm_connector_cleanup,
> > + .reset = drm_atomic_helper_connector_reset,
> > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> > + .atomic_destroy_state =
> > +drm_atomic_helper_connector_destroy_state,
> > +};
> > +
> > +static int amdgpu_vkms_conn_get_modes(struct drm_connector
> > +*connector) {
> > + int count;
> > +
> > + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> > + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> > +
> > + return count;
> > +}
> > +
> > +static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> > + .get_modes = amdgpu_vkms_conn_get_modes,
> > +};
> > +
> > +static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
> > + .update_plane = drm_atomic_helper_update_plane,
> > + .disable_plane = drm_atomic_helper_disable_plane,
> > + .destroy = drm_plane_cleanup,
> > + .reset = drm_atomic_helper_plane_reset,
> > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> > +};
> > +
> > +static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
> > + struct drm_plane_state
> > +*old_state) {
> > + return;
> > +}
> > +
> > +static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
> > + struct drm_plane_state
> > +*state) {
> > + struct drm_crtc_state *crtc_state;
> > + bool can_position = false;
> > + int ret;
> > +
> > + if (!state->fb || WARN_ON(!state->crtc))
> > + return 0;
> > +
> > + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> > + if (IS_ERR(crtc_state))
> > + return PTR_ERR(crtc_state);
> > +
> > + ret = drm_atomic_helper_check_plane_state(state, crtc_state,
> > + DRM_PLANE_HELPER_NO_SCALING,
> > + DRM_PLANE_HELPER_NO_SCALING,
> > + can_position, true);
> > + if (ret != 0)
> > + return ret;
> > +
> > + /* for now primary plane must be visible and full screen */
> > + if (!state->visible && !can_position)
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
> > + struct drm_plane_state *new_state) {
> > + struct amdgpu_framebuffer *afb;
> > + struct drm_gem_object *obj;
> > + struct amdgpu_device *adev;
> > + struct amdgpu_bo *rbo;
> > + struct list_head list;
> > + struct ttm_validate_buffer tv;
> > + struct ww_acquire_ctx ticket;
> > + uint32_t domain;
> > + int r;
> > +
> > + if (!new_state->fb) {
> > + DRM_DEBUG_KMS("No FB bound\n");
> > + return 0;
> > + }
> > + afb = to_amdgpu_framebuffer(new_state->fb);
> > + obj = new_state->fb->obj[0];
> > + rbo = gem_to_amdgpu_bo(obj);
> > + adev = amdgpu_ttm_adev(rbo->tbo.bdev);
> > + INIT_LIST_HEAD(&list);
> > +
> > + tv.bo = &rbo->tbo;
> > + tv.num_shared = 1;
> > + list_add(&tv.head, &list);
> > +
> > + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
> > + if (r) {
> > + dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
> > + return r;
> > + }
> > +
> > + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> > + domain = amdgpu_display_supported_domains(adev, rbo->flags);
> > + else
> > + domain = AMDGPU_GEM_DOMAIN_VRAM;
> > +
> > + r = amdgpu_bo_pin(rbo, domain);
> > + if (unlikely(r != 0)) {
> > + if (r != -ERESTARTSYS)
> > + DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
> > + ttm_eu_backoff_reservation(&ticket, &list);
> > + return r;
> > + }
> > +
> > + r = amdgpu_ttm_alloc_gart(&rbo->tbo);
> > + if (unlikely(r != 0)) {
> > + amdgpu_bo_unpin(rbo);
> > + ttm_eu_backoff_reservation(&ticket, &list);
> > + DRM_ERROR("%p bind failed\n", rbo);
> > + return r;
> > + }
> > +
> > + ttm_eu_backoff_reservation(&ticket, &list);
> > +
> > + afb->address = amdgpu_bo_gpu_offset(rbo);
> > +
> > + amdgpu_bo_ref(rbo);
> > +
> > + return 0;
> > +}
> > +
> > +static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
> > + struct drm_plane_state *old_state)
> > +{
> > + struct amdgpu_bo *rbo;
> > + int r;
> > +
> > + if (!old_state->fb)
> > + return;
> > +
> > + rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
> > + r = amdgpu_bo_reserve(rbo, false);
> > + if (unlikely(r)) {
> > + DRM_ERROR("failed to reserve rbo before unpin\n");
> > + return;
> > + }
> > +
> > + amdgpu_bo_unpin(rbo);
> > + amdgpu_bo_unreserve(rbo);
> > + amdgpu_bo_unref(&rbo);
> > +}
> > +
> > +static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
> > + .atomic_update = amdgpu_vkms_plane_atomic_update,
> > + .atomic_check = amdgpu_vkms_plane_atomic_check,
> > + .prepare_fb = amdgpu_vkms_prepare_fb,
> > + .cleanup_fb = amdgpu_vkms_cleanup_fb,
> > +};
> > +
> > +static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
> > + enum drm_plane_type type,
> > + int index) {
> > + struct drm_plane *plane;
> > + int ret;
> > +
> > + plane = kzalloc(sizeof(*plane), GFP_KERNEL);
> > + if (!plane)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + ret = drm_universal_plane_init(dev, plane, 1 << index,
> > + &amdgpu_vkms_plane_funcs,
> > + amdgpu_vkms_formats,
> > + ARRAY_SIZE(amdgpu_vkms_formats),
> > + NULL, type, NULL);
> > + if (ret) {
> > + kfree(plane);
> > + return ERR_PTR(ret);
> > + }
> > +
> > + drm_plane_helper_add(plane,
> > + &amdgpu_vkms_primary_helper_funcs);
> > +
> > + return plane;
> > +}
> > +
> > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > + struct amdgpu_vkms_output *output, int
> > +index) {
> > + struct drm_connector *connector = &output->connector;
> > + struct drm_encoder *encoder = &output->encoder;
> > + struct drm_crtc *crtc = &output->crtc;
> > + struct drm_plane *primary, *cursor = NULL;
> > + int ret;
> > +
> > + primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
> > + if (IS_ERR(primary))
> > + return PTR_ERR(primary);
> > +
> > + ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
> > + if (ret)
> > + goto err_crtc;
> > +
> > + ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
> > + DRM_MODE_CONNECTOR_VIRTUAL);
> > + if (ret) {
> > + DRM_ERROR("Failed to init connector\n");
> > + goto err_connector;
> > + }
> > +
> > + drm_connector_helper_add(connector,
> > + &amdgpu_vkms_conn_helper_funcs);
> > +
> > + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
> > + if (ret) {
> > + DRM_ERROR("Failed to init encoder\n");
> > + goto err_encoder;
> > + }
> > + encoder->possible_crtcs = 1 << index;
> > +
> > + ret = drm_connector_attach_encoder(connector, encoder);
> > + if (ret) {
> > + DRM_ERROR("Failed to attach connector to encoder\n");
> > + goto err_attach;
> > + }
> > +
> > + drm_mode_config_reset(dev);
> > +
> > + return 0;
> > +
> > +err_attach:
> > + drm_encoder_cleanup(encoder);
> > +
> > +err_encoder:
> > + drm_connector_cleanup(connector);
> > +
> > +err_connector:
> > + drm_crtc_cleanup(crtc);
> > +
> > +err_crtc:
> > + drm_plane_cleanup(primary);
> > +
> > + return ret;
> > +}
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > new file mode 100644
> > index 000000000000..5dab51fbecf3
> > --- /dev/null
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > @@ -0,0 +1,29 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +
> > +#ifndef _AMDGPU_VKMS_H_
> > +#define _AMDGPU_VKMS_H_
> > +
> > +#define XRES_DEF 1024
> > +#define YRES_DEF 764
>
> Squash in the 768 fix here.
>
> > +
> > +#define XRES_MAX 16384
> > +#define YRES_MAX 16384
> > +
> > +#define drm_crtc_to_amdgpu_vkms_output(target) \
> > + container_of(target, struct amdgpu_vkms_output, crtc)
> > +
> > +extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
> > +
> > +struct amdgpu_vkms_output {
> > + struct drm_crtc crtc;
> > + struct drm_encoder encoder;
> > + struct drm_connector connector;
> > + struct hrtimer vblank_hrtimer;
> > + ktime_t period_ns;
> > + struct drm_pending_vblank_event *event; };
> > +
> > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > + struct amdgpu_vkms_output *output, int
> > +index);
> > +
> > +#endif /* _AMDGPU_VKMS_H_ */
> > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > index 7e0d8c092c7e..642c77533157 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > @@ -22,6 +22,7 @@
> > */
> >
> > #include <drm/drm_vblank.h>
> > +#include <drm/drm_atomic_helper.h>
> >
> > #include "amdgpu.h"
> > #include "amdgpu_pm.h"
> > @@ -40,6 +41,7 @@
> > #include "dce_virtual.h"
> > #include "ivsrcid/ivsrcid_vislands30.h"
> > #include "amdgpu_display.h"
> > +#include "amdgpu_vkms.h"
> >
> > #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
> >
> > @@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> > .force = dce_virtual_force,
> > };
> >
> > +const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> > + .fb_create = amdgpu_display_user_framebuffer_create,
> > + .atomic_check = drm_atomic_helper_check,
> > + .atomic_commit = drm_atomic_helper_commit, };
> > +
> > static int dce_virtual_sw_init(void *handle) {
> > int r, i;
> > @@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
> >
> > adev_to_drm(adev)->max_vblank_count = 0;
> >
> > - adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
> > + adev_to_drm(adev)->mode_config.funcs =
> > + &dce_virtual_mode_funcs;
> >
> > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> > + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> >
> > adev_to_drm(adev)->mode_config.preferred_depth = 24;
> > adev_to_drm(adev)->mode_config.prefer_shadow = 1; @@ -399,15
> > +407,11 @@ static int dce_virtual_sw_init(void *handle)
> > if (r)
> > return r;
> >
> > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > + adev->amdgpu_vkms_output = kzalloc(sizeof(struct
> > + amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
>
> You can use kcalloc here.
>
> >
> > /* allocate crtcs, encoders, connectors */
> > for (i = 0; i < adev->mode_info.num_crtc; i++) {
> > - r = dce_virtual_crtc_init(adev, i);
> > - if (r)
> > - return r;
> > - r = dce_virtual_connector_encoder_init(adev, i);
> > + r = amdgpu_vkms_output_init(adev_to_drm(adev),
> > + &adev->amdgpu_vkms_output[i], i);
> > if (r)
> > return r;
> > }
> > @@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
> >
> > hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> >
> > kfree(adev->mode_info.bios_hardcoded_edid);
> > + kfree(adev->amdgpu_vkms_output);
> >
> > drm_kms_helper_poll_fini(adev_to_drm(adev));
> >
> > --
> > 2.32.0
> >
> > _______________________________________________
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flist
> > s.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cgu
> > chun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884
> > e608e11a82d994e183d%7C0%7C0%7C637626475284480052%7CUnknown%7CTWFpbGZsb
> > 3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> > 7C1000&sdata=0bbTKflaP2RPk%2BpboaNNiwffbEw1pW0zkqcxzPWjzmI%3D&
> > reserved=0
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cguchun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637626475284490043%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=VQ1liQG9OOsBA3NtjS93WNu6NhlLQ0fXQRbLwLmz95g%3D&reserved=0
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-26 16:21 ` Alex Deucher
@ 2021-07-26 16:39 ` Taylor, Ryan
2021-07-26 16:58 ` Alex Deucher
0 siblings, 1 reply; 13+ messages in thread
From: Taylor, Ryan @ 2021-07-26 16:39 UTC (permalink / raw)
To: Alex Deucher, Chen, Guchun
Cc: kernel test robot, Daniel Vetter, Siqueira, Rodrigo,
Maling list - DRI developers, Melissa Wen, amd-gfx list
[-- Attachment #1: Type: text/plain, Size: 27144 bytes --]
[AMD Official Use Only]
Given that amdgpu_vkms contains code from both dce_virtual and vkms should the identifier be changed to GPL-2.0+ OR MIT like in amdgpu_res_cursor.h?
Best,
Ryan
________________________________
From: Alex Deucher <alexdeucher@gmail.com>
Sent: Monday, July 26, 2021 9:21 AM
To: Chen, Guchun <Guchun.Chen@amd.com>
Cc: Taylor, Ryan <Ryan.Taylor@amd.com>; kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
On Fri, Jul 23, 2021 at 10:07 PM Chen, Guchun <Guchun.Chen@amd.com> wrote:
>
> [Public]
>
> Look copy right statement is missed in both amdgpu_vkms.c and amdgpu_vkms.h.
It's there, it just uses the newer SPDX license identifier.
Alex
>
> Regards,
> Guchun
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
> Sent: Friday, July 23, 2021 10:32 PM
> To: Taylor, Ryan <Ryan.Taylor@amd.com>
> Cc: kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
> Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
>
> On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
> >
> > Modify the VKMS driver into an api that dce_virtual can use to create
> > virtual displays that obey drm's atomic modesetting api.
> >
> > v2: Made local functions static.
> >
> > Reported-by: kernel test robot <lkp@intel.com>
> > Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> > ---
> > drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
> > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
> > drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
> > drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411
> > +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h |
> > 29 ++ drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
> > 7 files changed, 458 insertions(+), 11 deletions(-) create mode
> > 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile
> > b/drivers/gpu/drm/amd/amdgpu/Makefile
> > index f089794bbdd5..30cbcd5ce1cc 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> > @@ -120,6 +120,7 @@ amdgpu-y += \
> > amdgpu-y += \
> > dce_v10_0.o \
> > dce_v11_0.o \
> > + amdgpu_vkms.o \
> > dce_virtual.o
> >
> > # add GFX block
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > index 54cf647bd018..d0a2f2ed433d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > @@ -919,6 +919,7 @@ struct amdgpu_device {
> >
> > /* display */
> > bool enable_virtual_display;
> > + struct amdgpu_vkms_output *amdgpu_vkms_output;
> > struct amdgpu_mode_info mode_info;
> > /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
> > struct work_struct hotplug_work;
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > index d0c935cf4f0f..1b016e5bc75f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > @@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> > int ret, retry = 0;
> > bool supports_atomic = false;
> >
> > - if (!amdgpu_virtual_display &&
> > + if (amdgpu_virtual_display ||
> > amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
> > supports_atomic = true;
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > index 09b048647523..5a143ca02cf9 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
> > }
> >
> > /* disable all the possible outputs/crtcs before entering KMS mode */
> > - if (!amdgpu_device_has_dc_support(adev))
> > + if (!amdgpu_device_has_dc_support(adev) &&
> > + !amdgpu_virtual_display)
> >
> > drm_helper_disable_unused_functions(adev_to_drm(adev));
> >
> > drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); diff
> > --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > new file mode 100644
> > index 000000000000..d5c1f1c58f5f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > @@ -0,0 +1,411 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_simple_kms_helper.h> #include <drm/drm_vblank.h>
> > +
> > +#include "amdgpu.h"
> > +#include "amdgpu_vkms.h"
> > +#include "amdgpu_display.h"
> > +
> > +/**
> > + * DOC: amdgpu_vkms
> > + *
> > + * The amdgpu vkms interface provides a virtual KMS interface for
> > +several use
> > + * cases: devices without display hardware, platforms where the
> > +actual display
> > + * hardware is not useful (e.g., servers), SR-IOV virtual functions,
> > +device
> > + * emulation/simulation, and device bring up prior to display
> > +hardware being
> > + * usable. We previously emulated a legacy KMS interface, but there
> > +was a desire
> > + * to move to the atomic KMS interface. The vkms driver did
> > +everything we
> > + * needed, but we wanted KMS support natively in the driver without
> > +buffer
> > + * sharing and the ability to support an instance of VKMS per device.
> > +We first
> > + * looked at splitting vkms into a stub driver and a helper module
> > +that other
> > + * drivers could use to implement a virtual display, but this
> > +strategy ended up
> > + * being messy due to driver specific callbacks needed for buffer management.
> > + * Ultimately, it proved easier to import the vkms code as it mostly
> > +used core
> > + * drm helpers anyway.
> > + */
> > +
> > +static const u32 amdgpu_vkms_formats[] = {
> > + DRM_FORMAT_XRGB8888,
> > +};
> > +
> > +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct
> > +hrtimer *timer) {
> > + struct amdgpu_vkms_output *output = container_of(timer,
> > + struct amdgpu_vkms_output,
> > + vblank_hrtimer);
> > + struct drm_crtc *crtc = &output->crtc;
> > + u64 ret_overrun;
> > + bool ret;
> > +
> > + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
> > + output->period_ns);
> > + WARN_ON(ret_overrun != 1);
> > +
> > + ret = drm_crtc_handle_vblank(crtc);
> > + if (!ret)
> > + DRM_ERROR("amdgpu_vkms failure on handling vblank");
> > +
> > + return HRTIMER_RESTART;
> > +}
> > +
> > +static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc) {
> > + struct drm_device *dev = crtc->dev;
> > + unsigned int pipe = drm_crtc_index(crtc);
> > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > + struct amdgpu_vkms_output *out =
> > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > +
> > + drm_calc_timestamping_constants(crtc, &crtc->mode);
> > +
> > + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> > + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
> > + out->period_ns = ktime_set(0, vblank->framedur_ns);
> > + hrtimer_start(&out->vblank_hrtimer, out->period_ns,
> > + HRTIMER_MODE_REL);
> > +
> > + return 0;
> > +}
> > +
> > +static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) {
> > + struct amdgpu_vkms_output *out =
> > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > +
> > + hrtimer_cancel(&out->vblank_hrtimer);
> > +}
> > +
> > +static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> > + int *max_error,
> > + ktime_t *vblank_time,
> > + bool in_vblank_irq) {
> > + struct drm_device *dev = crtc->dev;
> > + unsigned int pipe = crtc->index;
> > + struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > +
> > + if (!READ_ONCE(vblank->enabled)) {
> > + *vblank_time = ktime_get();
> > + return true;
> > + }
> > +
> > + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
> > +
> > + if (WARN_ON(*vblank_time == vblank->time))
> > + return true;
> > +
> > + /*
> > + * To prevent races we roll the hrtimer forward before we do any
> > + * interrupt processing - this is how real hw works (the interrupt is
> > + * only generated after all the vblank registers are updated) and what
> > + * the vblank core expects. Therefore we need to always correct the
> > + * timestampe by one frame.
> > + */
> > + *vblank_time -= output->period_ns;
> > +
> > + return true;
> > +}
> > +
> > +static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
> > + .set_config = drm_atomic_helper_set_config,
> > + .destroy = drm_crtc_cleanup,
> > + .page_flip = drm_atomic_helper_page_flip,
> > + .reset = drm_atomic_helper_crtc_reset,
> > + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> > + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> > + .enable_vblank = amdgpu_vkms_enable_vblank,
> > + .disable_vblank = amdgpu_vkms_disable_vblank,
> > + .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
> > +};
> > +
> > +static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> > + struct drm_atomic_state
> > +*state) {
> > + drm_crtc_vblank_on(crtc);
> > +}
> > +
> > +static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> > + struct drm_atomic_state
> > +*state) {
> > + drm_crtc_vblank_off(crtc);
> > +}
> > +
> > +static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> > + struct drm_atomic_state
> > +*state) {
> > + if (crtc->state->event) {
> > + spin_lock(&crtc->dev->event_lock);
> > +
> > + if (drm_crtc_vblank_get(crtc) != 0)
> > + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> > + else
> > + drm_crtc_arm_vblank_event(crtc,
> > + crtc->state->event);
> > +
> > + spin_unlock(&crtc->dev->event_lock);
> > +
> > + crtc->state->event = NULL;
> > + }
> > +}
> > +
> > +static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> > + .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
> > + .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
> > + .atomic_disable = amdgpu_vkms_crtc_atomic_disable, };
> > +
> > +static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> > + struct drm_plane *primary, struct drm_plane
> > +*cursor) {
> > + int ret;
> > +
> > + ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
> > + &amdgpu_vkms_crtc_funcs, NULL);
> > + if (ret) {
> > + DRM_ERROR("Failed to init CRTC\n");
> > + return ret;
> > + }
> > +
> > + drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
> > +
> > + return ret;
> > +}
> > +
> > +static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
> > + .fill_modes = drm_helper_probe_single_connector_modes,
> > + .destroy = drm_connector_cleanup,
> > + .reset = drm_atomic_helper_connector_reset,
> > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> > + .atomic_destroy_state =
> > +drm_atomic_helper_connector_destroy_state,
> > +};
> > +
> > +static int amdgpu_vkms_conn_get_modes(struct drm_connector
> > +*connector) {
> > + int count;
> > +
> > + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> > + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> > +
> > + return count;
> > +}
> > +
> > +static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> > + .get_modes = amdgpu_vkms_conn_get_modes,
> > +};
> > +
> > +static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
> > + .update_plane = drm_atomic_helper_update_plane,
> > + .disable_plane = drm_atomic_helper_disable_plane,
> > + .destroy = drm_plane_cleanup,
> > + .reset = drm_atomic_helper_plane_reset,
> > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> > +};
> > +
> > +static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
> > + struct drm_plane_state
> > +*old_state) {
> > + return;
> > +}
> > +
> > +static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
> > + struct drm_plane_state
> > +*state) {
> > + struct drm_crtc_state *crtc_state;
> > + bool can_position = false;
> > + int ret;
> > +
> > + if (!state->fb || WARN_ON(!state->crtc))
> > + return 0;
> > +
> > + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> > + if (IS_ERR(crtc_state))
> > + return PTR_ERR(crtc_state);
> > +
> > + ret = drm_atomic_helper_check_plane_state(state, crtc_state,
> > + DRM_PLANE_HELPER_NO_SCALING,
> > + DRM_PLANE_HELPER_NO_SCALING,
> > + can_position, true);
> > + if (ret != 0)
> > + return ret;
> > +
> > + /* for now primary plane must be visible and full screen */
> > + if (!state->visible && !can_position)
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
> > + struct drm_plane_state *new_state) {
> > + struct amdgpu_framebuffer *afb;
> > + struct drm_gem_object *obj;
> > + struct amdgpu_device *adev;
> > + struct amdgpu_bo *rbo;
> > + struct list_head list;
> > + struct ttm_validate_buffer tv;
> > + struct ww_acquire_ctx ticket;
> > + uint32_t domain;
> > + int r;
> > +
> > + if (!new_state->fb) {
> > + DRM_DEBUG_KMS("No FB bound\n");
> > + return 0;
> > + }
> > + afb = to_amdgpu_framebuffer(new_state->fb);
> > + obj = new_state->fb->obj[0];
> > + rbo = gem_to_amdgpu_bo(obj);
> > + adev = amdgpu_ttm_adev(rbo->tbo.bdev);
> > + INIT_LIST_HEAD(&list);
> > +
> > + tv.bo = &rbo->tbo;
> > + tv.num_shared = 1;
> > + list_add(&tv.head, &list);
> > +
> > + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
> > + if (r) {
> > + dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
> > + return r;
> > + }
> > +
> > + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> > + domain = amdgpu_display_supported_domains(adev, rbo->flags);
> > + else
> > + domain = AMDGPU_GEM_DOMAIN_VRAM;
> > +
> > + r = amdgpu_bo_pin(rbo, domain);
> > + if (unlikely(r != 0)) {
> > + if (r != -ERESTARTSYS)
> > + DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
> > + ttm_eu_backoff_reservation(&ticket, &list);
> > + return r;
> > + }
> > +
> > + r = amdgpu_ttm_alloc_gart(&rbo->tbo);
> > + if (unlikely(r != 0)) {
> > + amdgpu_bo_unpin(rbo);
> > + ttm_eu_backoff_reservation(&ticket, &list);
> > + DRM_ERROR("%p bind failed\n", rbo);
> > + return r;
> > + }
> > +
> > + ttm_eu_backoff_reservation(&ticket, &list);
> > +
> > + afb->address = amdgpu_bo_gpu_offset(rbo);
> > +
> > + amdgpu_bo_ref(rbo);
> > +
> > + return 0;
> > +}
> > +
> > +static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
> > + struct drm_plane_state *old_state)
> > +{
> > + struct amdgpu_bo *rbo;
> > + int r;
> > +
> > + if (!old_state->fb)
> > + return;
> > +
> > + rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
> > + r = amdgpu_bo_reserve(rbo, false);
> > + if (unlikely(r)) {
> > + DRM_ERROR("failed to reserve rbo before unpin\n");
> > + return;
> > + }
> > +
> > + amdgpu_bo_unpin(rbo);
> > + amdgpu_bo_unreserve(rbo);
> > + amdgpu_bo_unref(&rbo);
> > +}
> > +
> > +static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
> > + .atomic_update = amdgpu_vkms_plane_atomic_update,
> > + .atomic_check = amdgpu_vkms_plane_atomic_check,
> > + .prepare_fb = amdgpu_vkms_prepare_fb,
> > + .cleanup_fb = amdgpu_vkms_cleanup_fb,
> > +};
> > +
> > +static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
> > + enum drm_plane_type type,
> > + int index) {
> > + struct drm_plane *plane;
> > + int ret;
> > +
> > + plane = kzalloc(sizeof(*plane), GFP_KERNEL);
> > + if (!plane)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + ret = drm_universal_plane_init(dev, plane, 1 << index,
> > + &amdgpu_vkms_plane_funcs,
> > + amdgpu_vkms_formats,
> > + ARRAY_SIZE(amdgpu_vkms_formats),
> > + NULL, type, NULL);
> > + if (ret) {
> > + kfree(plane);
> > + return ERR_PTR(ret);
> > + }
> > +
> > + drm_plane_helper_add(plane,
> > + &amdgpu_vkms_primary_helper_funcs);
> > +
> > + return plane;
> > +}
> > +
> > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > + struct amdgpu_vkms_output *output, int
> > +index) {
> > + struct drm_connector *connector = &output->connector;
> > + struct drm_encoder *encoder = &output->encoder;
> > + struct drm_crtc *crtc = &output->crtc;
> > + struct drm_plane *primary, *cursor = NULL;
> > + int ret;
> > +
> > + primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
> > + if (IS_ERR(primary))
> > + return PTR_ERR(primary);
> > +
> > + ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
> > + if (ret)
> > + goto err_crtc;
> > +
> > + ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
> > + DRM_MODE_CONNECTOR_VIRTUAL);
> > + if (ret) {
> > + DRM_ERROR("Failed to init connector\n");
> > + goto err_connector;
> > + }
> > +
> > + drm_connector_helper_add(connector,
> > + &amdgpu_vkms_conn_helper_funcs);
> > +
> > + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
> > + if (ret) {
> > + DRM_ERROR("Failed to init encoder\n");
> > + goto err_encoder;
> > + }
> > + encoder->possible_crtcs = 1 << index;
> > +
> > + ret = drm_connector_attach_encoder(connector, encoder);
> > + if (ret) {
> > + DRM_ERROR("Failed to attach connector to encoder\n");
> > + goto err_attach;
> > + }
> > +
> > + drm_mode_config_reset(dev);
> > +
> > + return 0;
> > +
> > +err_attach:
> > + drm_encoder_cleanup(encoder);
> > +
> > +err_encoder:
> > + drm_connector_cleanup(connector);
> > +
> > +err_connector:
> > + drm_crtc_cleanup(crtc);
> > +
> > +err_crtc:
> > + drm_plane_cleanup(primary);
> > +
> > + return ret;
> > +}
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > new file mode 100644
> > index 000000000000..5dab51fbecf3
> > --- /dev/null
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > @@ -0,0 +1,29 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +
> > +#ifndef _AMDGPU_VKMS_H_
> > +#define _AMDGPU_VKMS_H_
> > +
> > +#define XRES_DEF 1024
> > +#define YRES_DEF 764
>
> Squash in the 768 fix here.
>
> > +
> > +#define XRES_MAX 16384
> > +#define YRES_MAX 16384
> > +
> > +#define drm_crtc_to_amdgpu_vkms_output(target) \
> > + container_of(target, struct amdgpu_vkms_output, crtc)
> > +
> > +extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
> > +
> > +struct amdgpu_vkms_output {
> > + struct drm_crtc crtc;
> > + struct drm_encoder encoder;
> > + struct drm_connector connector;
> > + struct hrtimer vblank_hrtimer;
> > + ktime_t period_ns;
> > + struct drm_pending_vblank_event *event; };
> > +
> > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > + struct amdgpu_vkms_output *output, int
> > +index);
> > +
> > +#endif /* _AMDGPU_VKMS_H_ */
> > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > index 7e0d8c092c7e..642c77533157 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > @@ -22,6 +22,7 @@
> > */
> >
> > #include <drm/drm_vblank.h>
> > +#include <drm/drm_atomic_helper.h>
> >
> > #include "amdgpu.h"
> > #include "amdgpu_pm.h"
> > @@ -40,6 +41,7 @@
> > #include "dce_virtual.h"
> > #include "ivsrcid/ivsrcid_vislands30.h"
> > #include "amdgpu_display.h"
> > +#include "amdgpu_vkms.h"
> >
> > #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
> >
> > @@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> > .force = dce_virtual_force,
> > };
> >
> > +const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> > + .fb_create = amdgpu_display_user_framebuffer_create,
> > + .atomic_check = drm_atomic_helper_check,
> > + .atomic_commit = drm_atomic_helper_commit, };
> > +
> > static int dce_virtual_sw_init(void *handle) {
> > int r, i;
> > @@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
> >
> > adev_to_drm(adev)->max_vblank_count = 0;
> >
> > - adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
> > + adev_to_drm(adev)->mode_config.funcs =
> > + &dce_virtual_mode_funcs;
> >
> > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> > + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> >
> > adev_to_drm(adev)->mode_config.preferred_depth = 24;
> > adev_to_drm(adev)->mode_config.prefer_shadow = 1; @@ -399,15
> > +407,11 @@ static int dce_virtual_sw_init(void *handle)
> > if (r)
> > return r;
> >
> > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > + adev->amdgpu_vkms_output = kzalloc(sizeof(struct
> > + amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
>
> You can use kcalloc here.
>
> >
> > /* allocate crtcs, encoders, connectors */
> > for (i = 0; i < adev->mode_info.num_crtc; i++) {
> > - r = dce_virtual_crtc_init(adev, i);
> > - if (r)
> > - return r;
> > - r = dce_virtual_connector_encoder_init(adev, i);
> > + r = amdgpu_vkms_output_init(adev_to_drm(adev),
> > + &adev->amdgpu_vkms_output[i], i);
> > if (r)
> > return r;
> > }
> > @@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
> >
> > hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> >
> > kfree(adev->mode_info.bios_hardcoded_edid);
> > + kfree(adev->amdgpu_vkms_output);
> >
> > drm_kms_helper_poll_fini(adev_to_drm(adev));
> >
> > --
> > 2.32.0
> >
> > _______________________________________________
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flist
> > s.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cgu
> > chun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884
> > e608e11a82d994e183d%7C0%7C0%7C637626475284480052%7CUnknown%7CTWFpbGZsb
> > 3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> > 7C1000&sdata=0bbTKflaP2RPk%2BpboaNNiwffbEw1pW0zkqcxzPWjzmI%3D&
> > reserved=0
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CRyan.Taylor%40amd.com%7Ce0a16eb27da04a035cb608d950516493%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637629133975706919%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=KCe92Ic79b8lkS6h4GoZhRdhwehzleQrSH8OKlinX8I%3D&reserved=0
[-- Attachment #2: Type: text/html, Size: 54178 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-26 16:39 ` Taylor, Ryan
@ 2021-07-26 16:58 ` Alex Deucher
2021-07-26 17:02 ` Taylor, Ryan
0 siblings, 1 reply; 13+ messages in thread
From: Alex Deucher @ 2021-07-26 16:58 UTC (permalink / raw)
To: Taylor, Ryan
Cc: kernel test robot, Chen, Guchun, Daniel Vetter, Siqueira,
Rodrigo, amd-gfx list, Melissa Wen, Maling list - DRI developers
On Mon, Jul 26, 2021 at 12:39 PM Taylor, Ryan <Ryan.Taylor@amd.com> wrote:
>
> [AMD Official Use Only]
>
>
> Given that amdgpu_vkms contains code from both dce_virtual and vkms should the identifier be changed to GPL-2.0+ OR MIT like in amdgpu_res_cursor.h?
Most of the code is from vkms so match vkms.
Alex
>
> Best,
> Ryan
> ________________________________
> From: Alex Deucher <alexdeucher@gmail.com>
> Sent: Monday, July 26, 2021 9:21 AM
> To: Chen, Guchun <Guchun.Chen@amd.com>
> Cc: Taylor, Ryan <Ryan.Taylor@amd.com>; kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
> Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
>
> On Fri, Jul 23, 2021 at 10:07 PM Chen, Guchun <Guchun.Chen@amd.com> wrote:
> >
> > [Public]
> >
> > Look copy right statement is missed in both amdgpu_vkms.c and amdgpu_vkms.h.
>
> It's there, it just uses the newer SPDX license identifier.
>
> Alex
>
>
> >
> > Regards,
> > Guchun
> >
> > -----Original Message-----
> > From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
> > Sent: Friday, July 23, 2021 10:32 PM
> > To: Taylor, Ryan <Ryan.Taylor@amd.com>
> > Cc: kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
> > Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
> >
> > On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
> > >
> > > Modify the VKMS driver into an api that dce_virtual can use to create
> > > virtual displays that obey drm's atomic modesetting api.
> > >
> > > v2: Made local functions static.
> > >
> > > Reported-by: kernel test robot <lkp@intel.com>
> > > Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> > > ---
> > > drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
> > > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411
> > > +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h |
> > > 29 ++ drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
> > > 7 files changed, 458 insertions(+), 11 deletions(-) create mode
> > > 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile
> > > b/drivers/gpu/drm/amd/amdgpu/Makefile
> > > index f089794bbdd5..30cbcd5ce1cc 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> > > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> > > @@ -120,6 +120,7 @@ amdgpu-y += \
> > > amdgpu-y += \
> > > dce_v10_0.o \
> > > dce_v11_0.o \
> > > + amdgpu_vkms.o \
> > > dce_virtual.o
> > >
> > > # add GFX block
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > index 54cf647bd018..d0a2f2ed433d 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > @@ -919,6 +919,7 @@ struct amdgpu_device {
> > >
> > > /* display */
> > > bool enable_virtual_display;
> > > + struct amdgpu_vkms_output *amdgpu_vkms_output;
> > > struct amdgpu_mode_info mode_info;
> > > /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
> > > struct work_struct hotplug_work;
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > index d0c935cf4f0f..1b016e5bc75f 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > @@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> > > int ret, retry = 0;
> > > bool supports_atomic = false;
> > >
> > > - if (!amdgpu_virtual_display &&
> > > + if (amdgpu_virtual_display ||
> > > amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
> > > supports_atomic = true;
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > index 09b048647523..5a143ca02cf9 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
> > > }
> > >
> > > /* disable all the possible outputs/crtcs before entering KMS mode */
> > > - if (!amdgpu_device_has_dc_support(adev))
> > > + if (!amdgpu_device_has_dc_support(adev) &&
> > > + !amdgpu_virtual_display)
> > >
> > > drm_helper_disable_unused_functions(adev_to_drm(adev));
> > >
> > > drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); diff
> > > --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > new file mode 100644
> > > index 000000000000..d5c1f1c58f5f
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > @@ -0,0 +1,411 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +
> > > +#include <drm/drm_atomic_helper.h>
> > > +#include <drm/drm_simple_kms_helper.h> #include <drm/drm_vblank.h>
> > > +
> > > +#include "amdgpu.h"
> > > +#include "amdgpu_vkms.h"
> > > +#include "amdgpu_display.h"
> > > +
> > > +/**
> > > + * DOC: amdgpu_vkms
> > > + *
> > > + * The amdgpu vkms interface provides a virtual KMS interface for
> > > +several use
> > > + * cases: devices without display hardware, platforms where the
> > > +actual display
> > > + * hardware is not useful (e.g., servers), SR-IOV virtual functions,
> > > +device
> > > + * emulation/simulation, and device bring up prior to display
> > > +hardware being
> > > + * usable. We previously emulated a legacy KMS interface, but there
> > > +was a desire
> > > + * to move to the atomic KMS interface. The vkms driver did
> > > +everything we
> > > + * needed, but we wanted KMS support natively in the driver without
> > > +buffer
> > > + * sharing and the ability to support an instance of VKMS per device.
> > > +We first
> > > + * looked at splitting vkms into a stub driver and a helper module
> > > +that other
> > > + * drivers could use to implement a virtual display, but this
> > > +strategy ended up
> > > + * being messy due to driver specific callbacks needed for buffer management.
> > > + * Ultimately, it proved easier to import the vkms code as it mostly
> > > +used core
> > > + * drm helpers anyway.
> > > + */
> > > +
> > > +static const u32 amdgpu_vkms_formats[] = {
> > > + DRM_FORMAT_XRGB8888,
> > > +};
> > > +
> > > +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct
> > > +hrtimer *timer) {
> > > + struct amdgpu_vkms_output *output = container_of(timer,
> > > + struct amdgpu_vkms_output,
> > > + vblank_hrtimer);
> > > + struct drm_crtc *crtc = &output->crtc;
> > > + u64 ret_overrun;
> > > + bool ret;
> > > +
> > > + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
> > > + output->period_ns);
> > > + WARN_ON(ret_overrun != 1);
> > > +
> > > + ret = drm_crtc_handle_vblank(crtc);
> > > + if (!ret)
> > > + DRM_ERROR("amdgpu_vkms failure on handling vblank");
> > > +
> > > + return HRTIMER_RESTART;
> > > +}
> > > +
> > > +static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc) {
> > > + struct drm_device *dev = crtc->dev;
> > > + unsigned int pipe = drm_crtc_index(crtc);
> > > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > > + struct amdgpu_vkms_output *out =
> > > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > > +
> > > + drm_calc_timestamping_constants(crtc, &crtc->mode);
> > > +
> > > + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> > > + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
> > > + out->period_ns = ktime_set(0, vblank->framedur_ns);
> > > + hrtimer_start(&out->vblank_hrtimer, out->period_ns,
> > > + HRTIMER_MODE_REL);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) {
> > > + struct amdgpu_vkms_output *out =
> > > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > > +
> > > + hrtimer_cancel(&out->vblank_hrtimer);
> > > +}
> > > +
> > > +static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> > > + int *max_error,
> > > + ktime_t *vblank_time,
> > > + bool in_vblank_irq) {
> > > + struct drm_device *dev = crtc->dev;
> > > + unsigned int pipe = crtc->index;
> > > + struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> > > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > > +
> > > + if (!READ_ONCE(vblank->enabled)) {
> > > + *vblank_time = ktime_get();
> > > + return true;
> > > + }
> > > +
> > > + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
> > > +
> > > + if (WARN_ON(*vblank_time == vblank->time))
> > > + return true;
> > > +
> > > + /*
> > > + * To prevent races we roll the hrtimer forward before we do any
> > > + * interrupt processing - this is how real hw works (the interrupt is
> > > + * only generated after all the vblank registers are updated) and what
> > > + * the vblank core expects. Therefore we need to always correct the
> > > + * timestampe by one frame.
> > > + */
> > > + *vblank_time -= output->period_ns;
> > > +
> > > + return true;
> > > +}
> > > +
> > > +static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
> > > + .set_config = drm_atomic_helper_set_config,
> > > + .destroy = drm_crtc_cleanup,
> > > + .page_flip = drm_atomic_helper_page_flip,
> > > + .reset = drm_atomic_helper_crtc_reset,
> > > + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> > > + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> > > + .enable_vblank = amdgpu_vkms_enable_vblank,
> > > + .disable_vblank = amdgpu_vkms_disable_vblank,
> > > + .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
> > > +};
> > > +
> > > +static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> > > + struct drm_atomic_state
> > > +*state) {
> > > + drm_crtc_vblank_on(crtc);
> > > +}
> > > +
> > > +static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> > > + struct drm_atomic_state
> > > +*state) {
> > > + drm_crtc_vblank_off(crtc);
> > > +}
> > > +
> > > +static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> > > + struct drm_atomic_state
> > > +*state) {
> > > + if (crtc->state->event) {
> > > + spin_lock(&crtc->dev->event_lock);
> > > +
> > > + if (drm_crtc_vblank_get(crtc) != 0)
> > > + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> > > + else
> > > + drm_crtc_arm_vblank_event(crtc,
> > > + crtc->state->event);
> > > +
> > > + spin_unlock(&crtc->dev->event_lock);
> > > +
> > > + crtc->state->event = NULL;
> > > + }
> > > +}
> > > +
> > > +static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> > > + .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
> > > + .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
> > > + .atomic_disable = amdgpu_vkms_crtc_atomic_disable, };
> > > +
> > > +static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> > > + struct drm_plane *primary, struct drm_plane
> > > +*cursor) {
> > > + int ret;
> > > +
> > > + ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
> > > + &amdgpu_vkms_crtc_funcs, NULL);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to init CRTC\n");
> > > + return ret;
> > > + }
> > > +
> > > + drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
> > > + .fill_modes = drm_helper_probe_single_connector_modes,
> > > + .destroy = drm_connector_cleanup,
> > > + .reset = drm_atomic_helper_connector_reset,
> > > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> > > + .atomic_destroy_state =
> > > +drm_atomic_helper_connector_destroy_state,
> > > +};
> > > +
> > > +static int amdgpu_vkms_conn_get_modes(struct drm_connector
> > > +*connector) {
> > > + int count;
> > > +
> > > + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> > > + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> > > +
> > > + return count;
> > > +}
> > > +
> > > +static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> > > + .get_modes = amdgpu_vkms_conn_get_modes,
> > > +};
> > > +
> > > +static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
> > > + .update_plane = drm_atomic_helper_update_plane,
> > > + .disable_plane = drm_atomic_helper_disable_plane,
> > > + .destroy = drm_plane_cleanup,
> > > + .reset = drm_atomic_helper_plane_reset,
> > > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> > > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> > > +};
> > > +
> > > +static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
> > > + struct drm_plane_state
> > > +*old_state) {
> > > + return;
> > > +}
> > > +
> > > +static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
> > > + struct drm_plane_state
> > > +*state) {
> > > + struct drm_crtc_state *crtc_state;
> > > + bool can_position = false;
> > > + int ret;
> > > +
> > > + if (!state->fb || WARN_ON(!state->crtc))
> > > + return 0;
> > > +
> > > + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> > > + if (IS_ERR(crtc_state))
> > > + return PTR_ERR(crtc_state);
> > > +
> > > + ret = drm_atomic_helper_check_plane_state(state, crtc_state,
> > > + DRM_PLANE_HELPER_NO_SCALING,
> > > + DRM_PLANE_HELPER_NO_SCALING,
> > > + can_position, true);
> > > + if (ret != 0)
> > > + return ret;
> > > +
> > > + /* for now primary plane must be visible and full screen */
> > > + if (!state->visible && !can_position)
> > > + return -EINVAL;
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
> > > + struct drm_plane_state *new_state) {
> > > + struct amdgpu_framebuffer *afb;
> > > + struct drm_gem_object *obj;
> > > + struct amdgpu_device *adev;
> > > + struct amdgpu_bo *rbo;
> > > + struct list_head list;
> > > + struct ttm_validate_buffer tv;
> > > + struct ww_acquire_ctx ticket;
> > > + uint32_t domain;
> > > + int r;
> > > +
> > > + if (!new_state->fb) {
> > > + DRM_DEBUG_KMS("No FB bound\n");
> > > + return 0;
> > > + }
> > > + afb = to_amdgpu_framebuffer(new_state->fb);
> > > + obj = new_state->fb->obj[0];
> > > + rbo = gem_to_amdgpu_bo(obj);
> > > + adev = amdgpu_ttm_adev(rbo->tbo.bdev);
> > > + INIT_LIST_HEAD(&list);
> > > +
> > > + tv.bo = &rbo->tbo;
> > > + tv.num_shared = 1;
> > > + list_add(&tv.head, &list);
> > > +
> > > + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
> > > + if (r) {
> > > + dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
> > > + return r;
> > > + }
> > > +
> > > + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> > > + domain = amdgpu_display_supported_domains(adev, rbo->flags);
> > > + else
> > > + domain = AMDGPU_GEM_DOMAIN_VRAM;
> > > +
> > > + r = amdgpu_bo_pin(rbo, domain);
> > > + if (unlikely(r != 0)) {
> > > + if (r != -ERESTARTSYS)
> > > + DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
> > > + ttm_eu_backoff_reservation(&ticket, &list);
> > > + return r;
> > > + }
> > > +
> > > + r = amdgpu_ttm_alloc_gart(&rbo->tbo);
> > > + if (unlikely(r != 0)) {
> > > + amdgpu_bo_unpin(rbo);
> > > + ttm_eu_backoff_reservation(&ticket, &list);
> > > + DRM_ERROR("%p bind failed\n", rbo);
> > > + return r;
> > > + }
> > > +
> > > + ttm_eu_backoff_reservation(&ticket, &list);
> > > +
> > > + afb->address = amdgpu_bo_gpu_offset(rbo);
> > > +
> > > + amdgpu_bo_ref(rbo);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
> > > + struct drm_plane_state *old_state)
> > > +{
> > > + struct amdgpu_bo *rbo;
> > > + int r;
> > > +
> > > + if (!old_state->fb)
> > > + return;
> > > +
> > > + rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
> > > + r = amdgpu_bo_reserve(rbo, false);
> > > + if (unlikely(r)) {
> > > + DRM_ERROR("failed to reserve rbo before unpin\n");
> > > + return;
> > > + }
> > > +
> > > + amdgpu_bo_unpin(rbo);
> > > + amdgpu_bo_unreserve(rbo);
> > > + amdgpu_bo_unref(&rbo);
> > > +}
> > > +
> > > +static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
> > > + .atomic_update = amdgpu_vkms_plane_atomic_update,
> > > + .atomic_check = amdgpu_vkms_plane_atomic_check,
> > > + .prepare_fb = amdgpu_vkms_prepare_fb,
> > > + .cleanup_fb = amdgpu_vkms_cleanup_fb,
> > > +};
> > > +
> > > +static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
> > > + enum drm_plane_type type,
> > > + int index) {
> > > + struct drm_plane *plane;
> > > + int ret;
> > > +
> > > + plane = kzalloc(sizeof(*plane), GFP_KERNEL);
> > > + if (!plane)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + ret = drm_universal_plane_init(dev, plane, 1 << index,
> > > + &amdgpu_vkms_plane_funcs,
> > > + amdgpu_vkms_formats,
> > > + ARRAY_SIZE(amdgpu_vkms_formats),
> > > + NULL, type, NULL);
> > > + if (ret) {
> > > + kfree(plane);
> > > + return ERR_PTR(ret);
> > > + }
> > > +
> > > + drm_plane_helper_add(plane,
> > > + &amdgpu_vkms_primary_helper_funcs);
> > > +
> > > + return plane;
> > > +}
> > > +
> > > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > > + struct amdgpu_vkms_output *output, int
> > > +index) {
> > > + struct drm_connector *connector = &output->connector;
> > > + struct drm_encoder *encoder = &output->encoder;
> > > + struct drm_crtc *crtc = &output->crtc;
> > > + struct drm_plane *primary, *cursor = NULL;
> > > + int ret;
> > > +
> > > + primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
> > > + if (IS_ERR(primary))
> > > + return PTR_ERR(primary);
> > > +
> > > + ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
> > > + if (ret)
> > > + goto err_crtc;
> > > +
> > > + ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
> > > + DRM_MODE_CONNECTOR_VIRTUAL);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to init connector\n");
> > > + goto err_connector;
> > > + }
> > > +
> > > + drm_connector_helper_add(connector,
> > > + &amdgpu_vkms_conn_helper_funcs);
> > > +
> > > + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to init encoder\n");
> > > + goto err_encoder;
> > > + }
> > > + encoder->possible_crtcs = 1 << index;
> > > +
> > > + ret = drm_connector_attach_encoder(connector, encoder);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to attach connector to encoder\n");
> > > + goto err_attach;
> > > + }
> > > +
> > > + drm_mode_config_reset(dev);
> > > +
> > > + return 0;
> > > +
> > > +err_attach:
> > > + drm_encoder_cleanup(encoder);
> > > +
> > > +err_encoder:
> > > + drm_connector_cleanup(connector);
> > > +
> > > +err_connector:
> > > + drm_crtc_cleanup(crtc);
> > > +
> > > +err_crtc:
> > > + drm_plane_cleanup(primary);
> > > +
> > > + return ret;
> > > +}
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > > new file mode 100644
> > > index 000000000000..5dab51fbecf3
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > > @@ -0,0 +1,29 @@
> > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > +
> > > +#ifndef _AMDGPU_VKMS_H_
> > > +#define _AMDGPU_VKMS_H_
> > > +
> > > +#define XRES_DEF 1024
> > > +#define YRES_DEF 764
> >
> > Squash in the 768 fix here.
> >
> > > +
> > > +#define XRES_MAX 16384
> > > +#define YRES_MAX 16384
> > > +
> > > +#define drm_crtc_to_amdgpu_vkms_output(target) \
> > > + container_of(target, struct amdgpu_vkms_output, crtc)
> > > +
> > > +extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
> > > +
> > > +struct amdgpu_vkms_output {
> > > + struct drm_crtc crtc;
> > > + struct drm_encoder encoder;
> > > + struct drm_connector connector;
> > > + struct hrtimer vblank_hrtimer;
> > > + ktime_t period_ns;
> > > + struct drm_pending_vblank_event *event; };
> > > +
> > > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > > + struct amdgpu_vkms_output *output, int
> > > +index);
> > > +
> > > +#endif /* _AMDGPU_VKMS_H_ */
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > index 7e0d8c092c7e..642c77533157 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > @@ -22,6 +22,7 @@
> > > */
> > >
> > > #include <drm/drm_vblank.h>
> > > +#include <drm/drm_atomic_helper.h>
> > >
> > > #include "amdgpu.h"
> > > #include "amdgpu_pm.h"
> > > @@ -40,6 +41,7 @@
> > > #include "dce_virtual.h"
> > > #include "ivsrcid/ivsrcid_vislands30.h"
> > > #include "amdgpu_display.h"
> > > +#include "amdgpu_vkms.h"
> > >
> > > #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
> > >
> > > @@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> > > .force = dce_virtual_force,
> > > };
> > >
> > > +const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> > > + .fb_create = amdgpu_display_user_framebuffer_create,
> > > + .atomic_check = drm_atomic_helper_check,
> > > + .atomic_commit = drm_atomic_helper_commit, };
> > > +
> > > static int dce_virtual_sw_init(void *handle) {
> > > int r, i;
> > > @@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
> > >
> > > adev_to_drm(adev)->max_vblank_count = 0;
> > >
> > > - adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
> > > + adev_to_drm(adev)->mode_config.funcs =
> > > + &dce_virtual_mode_funcs;
> > >
> > > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > > + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> > > + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> > >
> > > adev_to_drm(adev)->mode_config.preferred_depth = 24;
> > > adev_to_drm(adev)->mode_config.prefer_shadow = 1; @@ -399,15
> > > +407,11 @@ static int dce_virtual_sw_init(void *handle)
> > > if (r)
> > > return r;
> > >
> > > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > > + adev->amdgpu_vkms_output = kzalloc(sizeof(struct
> > > + amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
> >
> > You can use kcalloc here.
> >
> > >
> > > /* allocate crtcs, encoders, connectors */
> > > for (i = 0; i < adev->mode_info.num_crtc; i++) {
> > > - r = dce_virtual_crtc_init(adev, i);
> > > - if (r)
> > > - return r;
> > > - r = dce_virtual_connector_encoder_init(adev, i);
> > > + r = amdgpu_vkms_output_init(adev_to_drm(adev),
> > > + &adev->amdgpu_vkms_output[i], i);
> > > if (r)
> > > return r;
> > > }
> > > @@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
> > >
> > > hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> > >
> > > kfree(adev->mode_info.bios_hardcoded_edid);
> > > + kfree(adev->amdgpu_vkms_output);
> > >
> > > drm_kms_helper_poll_fini(adev_to_drm(adev));
> > >
> > > --
> > > 2.32.0
> > >
> > > _______________________________________________
> > > amd-gfx mailing list
> > > amd-gfx@lists.freedesktop.org
> > > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flist
> > > s.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cgu
> > > chun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884
> > > e608e11a82d994e183d%7C0%7C0%7C637626475284480052%7CUnknown%7CTWFpbGZsb
> > > 3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> > > 7C1000&sdata=0bbTKflaP2RPk%2BpboaNNiwffbEw1pW0zkqcxzPWjzmI%3D&
> > > reserved=0
> > _______________________________________________
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CRyan.Taylor%40amd.com%7Ce0a16eb27da04a035cb608d950516493%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637629133975706919%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=KCe92Ic79b8lkS6h4GoZhRdhwehzleQrSH8OKlinX8I%3D&reserved=0
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
2021-07-26 16:58 ` Alex Deucher
@ 2021-07-26 17:02 ` Taylor, Ryan
0 siblings, 0 replies; 13+ messages in thread
From: Taylor, Ryan @ 2021-07-26 17:02 UTC (permalink / raw)
To: Alex Deucher
Cc: kernel test robot, Chen, Guchun, Daniel Vetter, Siqueira,
Rodrigo, amd-gfx list, Melissa Wen, Maling list - DRI developers
[-- Attachment #1: Type: text/plain, Size: 29268 bytes --]
[AMD Official Use Only]
Sounds good, Thanks for clarifying. Thanks for the input Guchun.
Best,
Ryan
________________________________
From: Alex Deucher <alexdeucher@gmail.com>
Sent: Monday, July 26, 2021 9:58 AM
To: Taylor, Ryan <Ryan.Taylor@amd.com>
Cc: Chen, Guchun <Guchun.Chen@amd.com>; kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
On Mon, Jul 26, 2021 at 12:39 PM Taylor, Ryan <Ryan.Taylor@amd.com> wrote:
>
> [AMD Official Use Only]
>
>
> Given that amdgpu_vkms contains code from both dce_virtual and vkms should the identifier be changed to GPL-2.0+ OR MIT like in amdgpu_res_cursor.h?
Most of the code is from vkms so match vkms.
Alex
>
> Best,
> Ryan
> ________________________________
> From: Alex Deucher <alexdeucher@gmail.com>
> Sent: Monday, July 26, 2021 9:21 AM
> To: Chen, Guchun <Guchun.Chen@amd.com>
> Cc: Taylor, Ryan <Ryan.Taylor@amd.com>; kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
> Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
>
> On Fri, Jul 23, 2021 at 10:07 PM Chen, Guchun <Guchun.Chen@amd.com> wrote:
> >
> > [Public]
> >
> > Look copy right statement is missed in both amdgpu_vkms.c and amdgpu_vkms.h.
>
> It's there, it just uses the newer SPDX license identifier.
>
> Alex
>
>
> >
> > Regards,
> > Guchun
> >
> > -----Original Message-----
> > From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
> > Sent: Friday, July 23, 2021 10:32 PM
> > To: Taylor, Ryan <Ryan.Taylor@amd.com>
> > Cc: kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; amd-gfx list <amd-gfx@lists.freedesktop.org>; Melissa Wen <melissa.srw@gmail.com>; Maling list - DRI developers <dri-devel@lists.freedesktop.org>
> > Subject: Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2)
> >
> > On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
> > >
> > > Modify the VKMS driver into an api that dce_virtual can use to create
> > > virtual displays that obey drm's atomic modesetting api.
> > >
> > > v2: Made local functions static.
> > >
> > > Reported-by: kernel test robot <lkp@intel.com>
> > > Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> > > ---
> > > drivers/gpu/drm/amd/amdgpu/Makefile | 1 +
> > > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 411
> > > +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h |
> > > 29 ++ drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +-
> > > 7 files changed, 458 insertions(+), 11 deletions(-) create mode
> > > 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile
> > > b/drivers/gpu/drm/amd/amdgpu/Makefile
> > > index f089794bbdd5..30cbcd5ce1cc 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> > > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> > > @@ -120,6 +120,7 @@ amdgpu-y += \
> > > amdgpu-y += \
> > > dce_v10_0.o \
> > > dce_v11_0.o \
> > > + amdgpu_vkms.o \
> > > dce_virtual.o
> > >
> > > # add GFX block
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > index 54cf647bd018..d0a2f2ed433d 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > > @@ -919,6 +919,7 @@ struct amdgpu_device {
> > >
> > > /* display */
> > > bool enable_virtual_display;
> > > + struct amdgpu_vkms_output *amdgpu_vkms_output;
> > > struct amdgpu_mode_info mode_info;
> > > /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
> > > struct work_struct hotplug_work;
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > index d0c935cf4f0f..1b016e5bc75f 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> > > @@ -1230,7 +1230,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
> > > int ret, retry = 0;
> > > bool supports_atomic = false;
> > >
> > > - if (!amdgpu_virtual_display &&
> > > + if (amdgpu_virtual_display ||
> > > amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
> > > supports_atomic = true;
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > index 09b048647523..5a143ca02cf9 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> > > @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
> > > }
> > >
> > > /* disable all the possible outputs/crtcs before entering KMS mode */
> > > - if (!amdgpu_device_has_dc_support(adev))
> > > + if (!amdgpu_device_has_dc_support(adev) &&
> > > + !amdgpu_virtual_display)
> > >
> > > drm_helper_disable_unused_functions(adev_to_drm(adev));
> > >
> > > drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); diff
> > > --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > new file mode 100644
> > > index 000000000000..d5c1f1c58f5f
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> > > @@ -0,0 +1,411 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +
> > > +#include <drm/drm_atomic_helper.h>
> > > +#include <drm/drm_simple_kms_helper.h> #include <drm/drm_vblank.h>
> > > +
> > > +#include "amdgpu.h"
> > > +#include "amdgpu_vkms.h"
> > > +#include "amdgpu_display.h"
> > > +
> > > +/**
> > > + * DOC: amdgpu_vkms
> > > + *
> > > + * The amdgpu vkms interface provides a virtual KMS interface for
> > > +several use
> > > + * cases: devices without display hardware, platforms where the
> > > +actual display
> > > + * hardware is not useful (e.g., servers), SR-IOV virtual functions,
> > > +device
> > > + * emulation/simulation, and device bring up prior to display
> > > +hardware being
> > > + * usable. We previously emulated a legacy KMS interface, but there
> > > +was a desire
> > > + * to move to the atomic KMS interface. The vkms driver did
> > > +everything we
> > > + * needed, but we wanted KMS support natively in the driver without
> > > +buffer
> > > + * sharing and the ability to support an instance of VKMS per device.
> > > +We first
> > > + * looked at splitting vkms into a stub driver and a helper module
> > > +that other
> > > + * drivers could use to implement a virtual display, but this
> > > +strategy ended up
> > > + * being messy due to driver specific callbacks needed for buffer management.
> > > + * Ultimately, it proved easier to import the vkms code as it mostly
> > > +used core
> > > + * drm helpers anyway.
> > > + */
> > > +
> > > +static const u32 amdgpu_vkms_formats[] = {
> > > + DRM_FORMAT_XRGB8888,
> > > +};
> > > +
> > > +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct
> > > +hrtimer *timer) {
> > > + struct amdgpu_vkms_output *output = container_of(timer,
> > > + struct amdgpu_vkms_output,
> > > + vblank_hrtimer);
> > > + struct drm_crtc *crtc = &output->crtc;
> > > + u64 ret_overrun;
> > > + bool ret;
> > > +
> > > + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
> > > + output->period_ns);
> > > + WARN_ON(ret_overrun != 1);
> > > +
> > > + ret = drm_crtc_handle_vblank(crtc);
> > > + if (!ret)
> > > + DRM_ERROR("amdgpu_vkms failure on handling vblank");
> > > +
> > > + return HRTIMER_RESTART;
> > > +}
> > > +
> > > +static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc) {
> > > + struct drm_device *dev = crtc->dev;
> > > + unsigned int pipe = drm_crtc_index(crtc);
> > > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > > + struct amdgpu_vkms_output *out =
> > > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > > +
> > > + drm_calc_timestamping_constants(crtc, &crtc->mode);
> > > +
> > > + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> > > + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
> > > + out->period_ns = ktime_set(0, vblank->framedur_ns);
> > > + hrtimer_start(&out->vblank_hrtimer, out->period_ns,
> > > + HRTIMER_MODE_REL);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) {
> > > + struct amdgpu_vkms_output *out =
> > > +drm_crtc_to_amdgpu_vkms_output(crtc);
> > > +
> > > + hrtimer_cancel(&out->vblank_hrtimer);
> > > +}
> > > +
> > > +static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> > > + int *max_error,
> > > + ktime_t *vblank_time,
> > > + bool in_vblank_irq) {
> > > + struct drm_device *dev = crtc->dev;
> > > + unsigned int pipe = crtc->index;
> > > + struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> > > + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> > > +
> > > + if (!READ_ONCE(vblank->enabled)) {
> > > + *vblank_time = ktime_get();
> > > + return true;
> > > + }
> > > +
> > > + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
> > > +
> > > + if (WARN_ON(*vblank_time == vblank->time))
> > > + return true;
> > > +
> > > + /*
> > > + * To prevent races we roll the hrtimer forward before we do any
> > > + * interrupt processing - this is how real hw works (the interrupt is
> > > + * only generated after all the vblank registers are updated) and what
> > > + * the vblank core expects. Therefore we need to always correct the
> > > + * timestampe by one frame.
> > > + */
> > > + *vblank_time -= output->period_ns;
> > > +
> > > + return true;
> > > +}
> > > +
> > > +static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
> > > + .set_config = drm_atomic_helper_set_config,
> > > + .destroy = drm_crtc_cleanup,
> > > + .page_flip = drm_atomic_helper_page_flip,
> > > + .reset = drm_atomic_helper_crtc_reset,
> > > + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> > > + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> > > + .enable_vblank = amdgpu_vkms_enable_vblank,
> > > + .disable_vblank = amdgpu_vkms_disable_vblank,
> > > + .get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
> > > +};
> > > +
> > > +static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> > > + struct drm_atomic_state
> > > +*state) {
> > > + drm_crtc_vblank_on(crtc);
> > > +}
> > > +
> > > +static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> > > + struct drm_atomic_state
> > > +*state) {
> > > + drm_crtc_vblank_off(crtc);
> > > +}
> > > +
> > > +static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> > > + struct drm_atomic_state
> > > +*state) {
> > > + if (crtc->state->event) {
> > > + spin_lock(&crtc->dev->event_lock);
> > > +
> > > + if (drm_crtc_vblank_get(crtc) != 0)
> > > + drm_crtc_send_vblank_event(crtc, crtc->state->event);
> > > + else
> > > + drm_crtc_arm_vblank_event(crtc,
> > > + crtc->state->event);
> > > +
> > > + spin_unlock(&crtc->dev->event_lock);
> > > +
> > > + crtc->state->event = NULL;
> > > + }
> > > +}
> > > +
> > > +static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> > > + .atomic_flush = amdgpu_vkms_crtc_atomic_flush,
> > > + .atomic_enable = amdgpu_vkms_crtc_atomic_enable,
> > > + .atomic_disable = amdgpu_vkms_crtc_atomic_disable, };
> > > +
> > > +static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> > > + struct drm_plane *primary, struct drm_plane
> > > +*cursor) {
> > > + int ret;
> > > +
> > > + ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
> > > + &amdgpu_vkms_crtc_funcs, NULL);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to init CRTC\n");
> > > + return ret;
> > > + }
> > > +
> > > + drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
> > > + .fill_modes = drm_helper_probe_single_connector_modes,
> > > + .destroy = drm_connector_cleanup,
> > > + .reset = drm_atomic_helper_connector_reset,
> > > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> > > + .atomic_destroy_state =
> > > +drm_atomic_helper_connector_destroy_state,
> > > +};
> > > +
> > > +static int amdgpu_vkms_conn_get_modes(struct drm_connector
> > > +*connector) {
> > > + int count;
> > > +
> > > + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> > > + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> > > +
> > > + return count;
> > > +}
> > > +
> > > +static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> > > + .get_modes = amdgpu_vkms_conn_get_modes,
> > > +};
> > > +
> > > +static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
> > > + .update_plane = drm_atomic_helper_update_plane,
> > > + .disable_plane = drm_atomic_helper_disable_plane,
> > > + .destroy = drm_plane_cleanup,
> > > + .reset = drm_atomic_helper_plane_reset,
> > > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> > > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> > > +};
> > > +
> > > +static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
> > > + struct drm_plane_state
> > > +*old_state) {
> > > + return;
> > > +}
> > > +
> > > +static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
> > > + struct drm_plane_state
> > > +*state) {
> > > + struct drm_crtc_state *crtc_state;
> > > + bool can_position = false;
> > > + int ret;
> > > +
> > > + if (!state->fb || WARN_ON(!state->crtc))
> > > + return 0;
> > > +
> > > + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> > > + if (IS_ERR(crtc_state))
> > > + return PTR_ERR(crtc_state);
> > > +
> > > + ret = drm_atomic_helper_check_plane_state(state, crtc_state,
> > > + DRM_PLANE_HELPER_NO_SCALING,
> > > + DRM_PLANE_HELPER_NO_SCALING,
> > > + can_position, true);
> > > + if (ret != 0)
> > > + return ret;
> > > +
> > > + /* for now primary plane must be visible and full screen */
> > > + if (!state->visible && !can_position)
> > > + return -EINVAL;
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
> > > + struct drm_plane_state *new_state) {
> > > + struct amdgpu_framebuffer *afb;
> > > + struct drm_gem_object *obj;
> > > + struct amdgpu_device *adev;
> > > + struct amdgpu_bo *rbo;
> > > + struct list_head list;
> > > + struct ttm_validate_buffer tv;
> > > + struct ww_acquire_ctx ticket;
> > > + uint32_t domain;
> > > + int r;
> > > +
> > > + if (!new_state->fb) {
> > > + DRM_DEBUG_KMS("No FB bound\n");
> > > + return 0;
> > > + }
> > > + afb = to_amdgpu_framebuffer(new_state->fb);
> > > + obj = new_state->fb->obj[0];
> > > + rbo = gem_to_amdgpu_bo(obj);
> > > + adev = amdgpu_ttm_adev(rbo->tbo.bdev);
> > > + INIT_LIST_HEAD(&list);
> > > +
> > > + tv.bo = &rbo->tbo;
> > > + tv.num_shared = 1;
> > > + list_add(&tv.head, &list);
> > > +
> > > + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
> > > + if (r) {
> > > + dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
> > > + return r;
> > > + }
> > > +
> > > + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> > > + domain = amdgpu_display_supported_domains(adev, rbo->flags);
> > > + else
> > > + domain = AMDGPU_GEM_DOMAIN_VRAM;
> > > +
> > > + r = amdgpu_bo_pin(rbo, domain);
> > > + if (unlikely(r != 0)) {
> > > + if (r != -ERESTARTSYS)
> > > + DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
> > > + ttm_eu_backoff_reservation(&ticket, &list);
> > > + return r;
> > > + }
> > > +
> > > + r = amdgpu_ttm_alloc_gart(&rbo->tbo);
> > > + if (unlikely(r != 0)) {
> > > + amdgpu_bo_unpin(rbo);
> > > + ttm_eu_backoff_reservation(&ticket, &list);
> > > + DRM_ERROR("%p bind failed\n", rbo);
> > > + return r;
> > > + }
> > > +
> > > + ttm_eu_backoff_reservation(&ticket, &list);
> > > +
> > > + afb->address = amdgpu_bo_gpu_offset(rbo);
> > > +
> > > + amdgpu_bo_ref(rbo);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
> > > + struct drm_plane_state *old_state)
> > > +{
> > > + struct amdgpu_bo *rbo;
> > > + int r;
> > > +
> > > + if (!old_state->fb)
> > > + return;
> > > +
> > > + rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
> > > + r = amdgpu_bo_reserve(rbo, false);
> > > + if (unlikely(r)) {
> > > + DRM_ERROR("failed to reserve rbo before unpin\n");
> > > + return;
> > > + }
> > > +
> > > + amdgpu_bo_unpin(rbo);
> > > + amdgpu_bo_unreserve(rbo);
> > > + amdgpu_bo_unref(&rbo);
> > > +}
> > > +
> > > +static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
> > > + .atomic_update = amdgpu_vkms_plane_atomic_update,
> > > + .atomic_check = amdgpu_vkms_plane_atomic_check,
> > > + .prepare_fb = amdgpu_vkms_prepare_fb,
> > > + .cleanup_fb = amdgpu_vkms_cleanup_fb,
> > > +};
> > > +
> > > +static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
> > > + enum drm_plane_type type,
> > > + int index) {
> > > + struct drm_plane *plane;
> > > + int ret;
> > > +
> > > + plane = kzalloc(sizeof(*plane), GFP_KERNEL);
> > > + if (!plane)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + ret = drm_universal_plane_init(dev, plane, 1 << index,
> > > + &amdgpu_vkms_plane_funcs,
> > > + amdgpu_vkms_formats,
> > > + ARRAY_SIZE(amdgpu_vkms_formats),
> > > + NULL, type, NULL);
> > > + if (ret) {
> > > + kfree(plane);
> > > + return ERR_PTR(ret);
> > > + }
> > > +
> > > + drm_plane_helper_add(plane,
> > > + &amdgpu_vkms_primary_helper_funcs);
> > > +
> > > + return plane;
> > > +}
> > > +
> > > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > > + struct amdgpu_vkms_output *output, int
> > > +index) {
> > > + struct drm_connector *connector = &output->connector;
> > > + struct drm_encoder *encoder = &output->encoder;
> > > + struct drm_crtc *crtc = &output->crtc;
> > > + struct drm_plane *primary, *cursor = NULL;
> > > + int ret;
> > > +
> > > + primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
> > > + if (IS_ERR(primary))
> > > + return PTR_ERR(primary);
> > > +
> > > + ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
> > > + if (ret)
> > > + goto err_crtc;
> > > +
> > > + ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
> > > + DRM_MODE_CONNECTOR_VIRTUAL);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to init connector\n");
> > > + goto err_connector;
> > > + }
> > > +
> > > + drm_connector_helper_add(connector,
> > > + &amdgpu_vkms_conn_helper_funcs);
> > > +
> > > + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to init encoder\n");
> > > + goto err_encoder;
> > > + }
> > > + encoder->possible_crtcs = 1 << index;
> > > +
> > > + ret = drm_connector_attach_encoder(connector, encoder);
> > > + if (ret) {
> > > + DRM_ERROR("Failed to attach connector to encoder\n");
> > > + goto err_attach;
> > > + }
> > > +
> > > + drm_mode_config_reset(dev);
> > > +
> > > + return 0;
> > > +
> > > +err_attach:
> > > + drm_encoder_cleanup(encoder);
> > > +
> > > +err_encoder:
> > > + drm_connector_cleanup(connector);
> > > +
> > > +err_connector:
> > > + drm_crtc_cleanup(crtc);
> > > +
> > > +err_crtc:
> > > + drm_plane_cleanup(primary);
> > > +
> > > + return ret;
> > > +}
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > > new file mode 100644
> > > index 000000000000..5dab51fbecf3
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> > > @@ -0,0 +1,29 @@
> > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > +
> > > +#ifndef _AMDGPU_VKMS_H_
> > > +#define _AMDGPU_VKMS_H_
> > > +
> > > +#define XRES_DEF 1024
> > > +#define YRES_DEF 764
> >
> > Squash in the 768 fix here.
> >
> > > +
> > > +#define XRES_MAX 16384
> > > +#define YRES_MAX 16384
> > > +
> > > +#define drm_crtc_to_amdgpu_vkms_output(target) \
> > > + container_of(target, struct amdgpu_vkms_output, crtc)
> > > +
> > > +extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
> > > +
> > > +struct amdgpu_vkms_output {
> > > + struct drm_crtc crtc;
> > > + struct drm_encoder encoder;
> > > + struct drm_connector connector;
> > > + struct hrtimer vblank_hrtimer;
> > > + ktime_t period_ns;
> > > + struct drm_pending_vblank_event *event; };
> > > +
> > > +int amdgpu_vkms_output_init(struct drm_device *dev,
> > > + struct amdgpu_vkms_output *output, int
> > > +index);
> > > +
> > > +#endif /* _AMDGPU_VKMS_H_ */
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > index 7e0d8c092c7e..642c77533157 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> > > @@ -22,6 +22,7 @@
> > > */
> > >
> > > #include <drm/drm_vblank.h>
> > > +#include <drm/drm_atomic_helper.h>
> > >
> > > #include "amdgpu.h"
> > > #include "amdgpu_pm.h"
> > > @@ -40,6 +41,7 @@
> > > #include "dce_virtual.h"
> > > #include "ivsrcid/ivsrcid_vislands30.h"
> > > #include "amdgpu_display.h"
> > > +#include "amdgpu_vkms.h"
> > >
> > > #define DCE_VIRTUAL_VBLANK_PERIOD 16666666
> > >
> > > @@ -374,6 +376,12 @@ static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> > > .force = dce_virtual_force,
> > > };
> > >
> > > +const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> > > + .fb_create = amdgpu_display_user_framebuffer_create,
> > > + .atomic_check = drm_atomic_helper_check,
> > > + .atomic_commit = drm_atomic_helper_commit, };
> > > +
> > > static int dce_virtual_sw_init(void *handle) {
> > > int r, i;
> > > @@ -385,10 +393,10 @@ static int dce_virtual_sw_init(void *handle)
> > >
> > > adev_to_drm(adev)->max_vblank_count = 0;
> > >
> > > - adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
> > > + adev_to_drm(adev)->mode_config.funcs =
> > > + &dce_virtual_mode_funcs;
> > >
> > > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > > + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> > > + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> > >
> > > adev_to_drm(adev)->mode_config.preferred_depth = 24;
> > > adev_to_drm(adev)->mode_config.prefer_shadow = 1; @@ -399,15
> > > +407,11 @@ static int dce_virtual_sw_init(void *handle)
> > > if (r)
> > > return r;
> > >
> > > - adev_to_drm(adev)->mode_config.max_width = 16384;
> > > - adev_to_drm(adev)->mode_config.max_height = 16384;
> > > + adev->amdgpu_vkms_output = kzalloc(sizeof(struct
> > > + amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
> >
> > You can use kcalloc here.
> >
> > >
> > > /* allocate crtcs, encoders, connectors */
> > > for (i = 0; i < adev->mode_info.num_crtc; i++) {
> > > - r = dce_virtual_crtc_init(adev, i);
> > > - if (r)
> > > - return r;
> > > - r = dce_virtual_connector_encoder_init(adev, i);
> > > + r = amdgpu_vkms_output_init(adev_to_drm(adev),
> > > + &adev->amdgpu_vkms_output[i], i);
> > > if (r)
> > > return r;
> > > }
> > > @@ -428,6 +432,7 @@ static int dce_virtual_sw_fini(void *handle)
> > >
> > > hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> > >
> > > kfree(adev->mode_info.bios_hardcoded_edid);
> > > + kfree(adev->amdgpu_vkms_output);
> > >
> > > drm_kms_helper_poll_fini(adev_to_drm(adev));
> > >
> > > --
> > > 2.32.0
> > >
> > > _______________________________________________
> > > amd-gfx mailing list
> > > amd-gfx@lists.freedesktop.org
> > > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flist
> > > s.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cgu
> > > chun.chen%40amd.com%7Ce4b064b3485c4865df8608d94de6a58e%7C3dd8961fe4884
> > > e608e11a82d994e183d%7C0%7C0%7C637626475284480052%7CUnknown%7CTWFpbGZsb
> > > 3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> > > 7C1000&sdata=0bbTKflaP2RPk%2BpboaNNiwffbEw1pW0zkqcxzPWjzmI%3D&
> > > reserved=0
> > _______________________________________________
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CRyan.Taylor%40amd.com%7Cbaa2d803835b411fdc0408d95056aa89%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637629155949319404%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=gqJcTtUbjxhBYg2k5rg1KunDoCJxPi%2BrrLOKrLb10RM%3D&reserved=0
[-- Attachment #2: Type: text/html, Size: 58488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3] drm/amdgpu: cleanup dce_virtual
2021-07-21 17:07 [PATCH 0/3] drm/amdgpu: modernize virtual display feature Ryan Taylor
2021-07-21 17:07 ` [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2) Ryan Taylor
@ 2021-07-21 17:07 ` Ryan Taylor
2021-07-21 17:07 ` [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3) Ryan Taylor
2 siblings, 0 replies; 13+ messages in thread
From: Ryan Taylor @ 2021-07-21 17:07 UTC (permalink / raw)
To: dri-devel, amd-gfx
Cc: melissa.srw, daniel.vetter, rodrigo.siqueira, Ryan Taylor
Remove obsolete functions and variables from dce_virtual.
Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
---
drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 568 +----------------------
1 file changed, 3 insertions(+), 565 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 642c77533157..18369b47eac7 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -21,15 +21,9 @@
*
*/
-#include <drm/drm_vblank.h>
#include <drm/drm_atomic_helper.h>
#include "amdgpu.h"
-#include "amdgpu_pm.h"
-#include "amdgpu_i2c.h"
-#include "atom.h"
-#include "amdgpu_pll.h"
-#include "amdgpu_connectors.h"
#ifdef CONFIG_DRM_AMDGPU_SI
#include "dce_v6_0.h"
#endif
@@ -43,339 +37,6 @@
#include "amdgpu_display.h"
#include "amdgpu_vkms.h"
-#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
-
-
-static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
-static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
-static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
- int index);
-static int dce_virtual_pageflip(struct amdgpu_device *adev,
- unsigned crtc_id);
-static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer);
-static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
- int crtc,
- enum amdgpu_interrupt_state state);
-
-static u32 dce_virtual_vblank_get_counter(struct amdgpu_device *adev, int crtc)
-{
- return 0;
-}
-
-static void dce_virtual_page_flip(struct amdgpu_device *adev,
- int crtc_id, u64 crtc_base, bool async)
-{
- return;
-}
-
-static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
- u32 *vbl, u32 *position)
-{
- *vbl = 0;
- *position = 0;
-
- return -EINVAL;
-}
-
-static bool dce_virtual_hpd_sense(struct amdgpu_device *adev,
- enum amdgpu_hpd_id hpd)
-{
- return true;
-}
-
-static void dce_virtual_hpd_set_polarity(struct amdgpu_device *adev,
- enum amdgpu_hpd_id hpd)
-{
- return;
-}
-
-static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev)
-{
- return 0;
-}
-
-/**
- * dce_virtual_bandwidth_update - program display watermarks
- *
- * @adev: amdgpu_device pointer
- *
- * Calculate and program the display watermarks and line
- * buffer allocation (CIK).
- */
-static void dce_virtual_bandwidth_update(struct amdgpu_device *adev)
-{
- return;
-}
-
-static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
- u16 *green, u16 *blue, uint32_t size,
- struct drm_modeset_acquire_ctx *ctx)
-{
- return 0;
-}
-
-static void dce_virtual_crtc_destroy(struct drm_crtc *crtc)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
-
- drm_crtc_cleanup(crtc);
- kfree(amdgpu_crtc);
-}
-
-static const struct drm_crtc_funcs dce_virtual_crtc_funcs = {
- .cursor_set2 = NULL,
- .cursor_move = NULL,
- .gamma_set = dce_virtual_crtc_gamma_set,
- .set_config = amdgpu_display_crtc_set_config,
- .destroy = dce_virtual_crtc_destroy,
- .page_flip_target = amdgpu_display_crtc_page_flip_target,
- .get_vblank_counter = amdgpu_get_vblank_counter_kms,
- .enable_vblank = amdgpu_enable_vblank_kms,
- .disable_vblank = amdgpu_disable_vblank_kms,
- .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
-};
-
-static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct drm_device *dev = crtc->dev;
- struct amdgpu_device *adev = drm_to_adev(dev);
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- unsigned type;
-
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- amdgpu_crtc->enabled = true;
- /* Make sure VBLANK interrupts are still enabled */
- type = amdgpu_display_crtc_idx_to_irq_type(adev,
- amdgpu_crtc->crtc_id);
- amdgpu_irq_update(adev, &adev->crtc_irq, type);
- drm_crtc_vblank_on(crtc);
- break;
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- case DRM_MODE_DPMS_OFF:
- drm_crtc_vblank_off(crtc);
- amdgpu_crtc->enabled = false;
- break;
- }
-}
-
-
-static void dce_virtual_crtc_prepare(struct drm_crtc *crtc)
-{
- dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void dce_virtual_crtc_commit(struct drm_crtc *crtc)
-{
- dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- struct drm_device *dev = crtc->dev;
-
- if (dev->num_crtcs)
- drm_crtc_vblank_off(crtc);
-
- amdgpu_crtc->enabled = false;
- amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
- amdgpu_crtc->encoder = NULL;
- amdgpu_crtc->connector = NULL;
-}
-
-static int dce_virtual_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y, struct drm_framebuffer *old_fb)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
-
- /* update the hw version fpr dpm */
- amdgpu_crtc->hw_mode = *adjusted_mode;
-
- return 0;
-}
-
-static bool dce_virtual_crtc_mode_fixup(struct drm_crtc *crtc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
-
-static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
-{
- return 0;
-}
-
-static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- int x, int y, enum mode_set_atomic state)
-{
- return 0;
-}
-
-static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
- .dpms = dce_virtual_crtc_dpms,
- .mode_fixup = dce_virtual_crtc_mode_fixup,
- .mode_set = dce_virtual_crtc_mode_set,
- .mode_set_base = dce_virtual_crtc_set_base,
- .mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
- .prepare = dce_virtual_crtc_prepare,
- .commit = dce_virtual_crtc_commit,
- .disable = dce_virtual_crtc_disable,
- .get_scanout_position = amdgpu_crtc_get_scanout_position,
-};
-
-static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
-{
- struct amdgpu_crtc *amdgpu_crtc;
-
- amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
- (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
- if (amdgpu_crtc == NULL)
- return -ENOMEM;
-
- drm_crtc_init(adev_to_drm(adev), &amdgpu_crtc->base, &dce_virtual_crtc_funcs);
-
- drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256);
- amdgpu_crtc->crtc_id = index;
- adev->mode_info.crtcs[index] = amdgpu_crtc;
-
- amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
- amdgpu_crtc->encoder = NULL;
- amdgpu_crtc->connector = NULL;
- amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
- drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs);
-
- hrtimer_init(&amdgpu_crtc->vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hrtimer_set_expires(&amdgpu_crtc->vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD);
- amdgpu_crtc->vblank_timer.function = dce_virtual_vblank_timer_handle;
- hrtimer_start(&amdgpu_crtc->vblank_timer,
- DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL);
- return 0;
-}
-
-static int dce_virtual_early_init(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-
- dce_virtual_set_display_funcs(adev);
- dce_virtual_set_irq_funcs(adev);
-
- adev->mode_info.num_hpd = 1;
- adev->mode_info.num_dig = 1;
- return 0;
-}
-
-static struct drm_encoder *
-dce_virtual_encoder(struct drm_connector *connector)
-{
- struct drm_encoder *encoder;
-
- drm_connector_for_each_possible_encoder(connector, encoder) {
- if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
- return encoder;
- }
-
- /* pick the first one */
- drm_connector_for_each_possible_encoder(connector, encoder)
- return encoder;
-
- return NULL;
-}
-
-static int dce_virtual_get_modes(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct drm_display_mode *mode = NULL;
- unsigned i;
- static const struct mode_size {
- int w;
- int h;
- } common_modes[] = {
- { 640, 480},
- { 720, 480},
- { 800, 600},
- { 848, 480},
- {1024, 768},
- {1152, 768},
- {1280, 720},
- {1280, 800},
- {1280, 854},
- {1280, 960},
- {1280, 1024},
- {1440, 900},
- {1400, 1050},
- {1680, 1050},
- {1600, 1200},
- {1920, 1080},
- {1920, 1200},
- {2560, 1440},
- {4096, 3112},
- {3656, 2664},
- {3840, 2160},
- {4096, 2160},
- };
-
- for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
- mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
- drm_mode_probed_add(connector, mode);
- }
-
- return 0;
-}
-
-static enum drm_mode_status dce_virtual_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- return MODE_OK;
-}
-
-static int
-dce_virtual_dpms(struct drm_connector *connector, int mode)
-{
- return 0;
-}
-
-static int
-dce_virtual_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t val)
-{
- return 0;
-}
-
-static void dce_virtual_destroy(struct drm_connector *connector)
-{
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
-static void dce_virtual_force(struct drm_connector *connector)
-{
- return;
-}
-
-static const struct drm_connector_helper_funcs dce_virtual_connector_helper_funcs = {
- .get_modes = dce_virtual_get_modes,
- .mode_valid = dce_virtual_mode_valid,
- .best_encoder = dce_virtual_encoder,
-};
-
-static const struct drm_connector_funcs dce_virtual_connector_funcs = {
- .dpms = dce_virtual_dpms,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = dce_virtual_set_property,
- .destroy = dce_virtual_destroy,
- .force = dce_virtual_force,
-};
-
const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
.fb_create = amdgpu_display_user_framebuffer_create,
.atomic_check = drm_atomic_helper_check,
@@ -387,10 +48,6 @@ static int dce_virtual_sw_init(void *handle)
int r, i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq);
- if (r)
- return r;
-
adev_to_drm(adev)->max_vblank_count = 0;
adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
@@ -436,9 +93,6 @@ static int dce_virtual_sw_fini(void *handle)
drm_kms_helper_poll_fini(adev_to_drm(adev));
- drm_mode_config_cleanup(adev_to_drm(adev));
- /* clear crtcs pointer to avoid dce irq finish routine access freed data */
- memset(adev->mode_info.crtcs, 0, sizeof(adev->mode_info.crtcs[0]) * AMDGPU_MAX_CRTCS);
adev->mode_info.mode_config_initialized = false;
return 0;
}
@@ -498,7 +152,7 @@ static int dce_virtual_suspend(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
- r = amdgpu_display_suspend_helper(adev);
+ r = drm_mode_config_helper_suspend(adev_to_drm(adev));
if (r)
return r;
return dce_virtual_hw_fini(handle);
@@ -512,7 +166,7 @@ static int dce_virtual_resume(void *handle)
r = dce_virtual_hw_init(handle);
if (r)
return r;
- return amdgpu_display_resume_helper(adev);
+ return drm_mode_config_helper_resume(adev_to_drm(adev));
}
static bool dce_virtual_is_idle(void *handle)
@@ -544,7 +198,7 @@ static int dce_virtual_set_powergating_state(void *handle,
static const struct amd_ip_funcs dce_virtual_ip_funcs = {
.name = "dce_virtual",
- .early_init = dce_virtual_early_init,
+ .early_init = NULL,
.late_init = NULL,
.sw_init = dce_virtual_sw_init,
.sw_fini = dce_virtual_sw_fini,
@@ -559,222 +213,6 @@ static const struct amd_ip_funcs dce_virtual_ip_funcs = {
.set_powergating_state = dce_virtual_set_powergating_state,
};
-/* these are handled by the primary encoders */
-static void dce_virtual_encoder_prepare(struct drm_encoder *encoder)
-{
- return;
-}
-
-static void dce_virtual_encoder_commit(struct drm_encoder *encoder)
-{
- return;
-}
-
-static void
-dce_virtual_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return;
-}
-
-static void dce_virtual_encoder_disable(struct drm_encoder *encoder)
-{
- return;
-}
-
-static void
-dce_virtual_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- return;
-}
-
-static bool dce_virtual_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
-static const struct drm_encoder_helper_funcs dce_virtual_encoder_helper_funcs = {
- .dpms = dce_virtual_encoder_dpms,
- .mode_fixup = dce_virtual_encoder_mode_fixup,
- .prepare = dce_virtual_encoder_prepare,
- .mode_set = dce_virtual_encoder_mode_set,
- .commit = dce_virtual_encoder_commit,
- .disable = dce_virtual_encoder_disable,
-};
-
-static void dce_virtual_encoder_destroy(struct drm_encoder *encoder)
-{
- drm_encoder_cleanup(encoder);
- kfree(encoder);
-}
-
-static const struct drm_encoder_funcs dce_virtual_encoder_funcs = {
- .destroy = dce_virtual_encoder_destroy,
-};
-
-static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
- int index)
-{
- struct drm_encoder *encoder;
- struct drm_connector *connector;
-
- /* add a new encoder */
- encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL);
- if (!encoder)
- return -ENOMEM;
- encoder->possible_crtcs = 1 << index;
- drm_encoder_init(adev_to_drm(adev), encoder, &dce_virtual_encoder_funcs,
- DRM_MODE_ENCODER_VIRTUAL, NULL);
- drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs);
-
- connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
- if (!connector) {
- kfree(encoder);
- return -ENOMEM;
- }
-
- /* add a new connector */
- drm_connector_init(adev_to_drm(adev), connector, &dce_virtual_connector_funcs,
- DRM_MODE_CONNECTOR_VIRTUAL);
- drm_connector_helper_add(connector, &dce_virtual_connector_helper_funcs);
- connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- connector->interlace_allowed = false;
- connector->doublescan_allowed = false;
-
- /* link them */
- drm_connector_attach_encoder(connector, encoder);
-
- return 0;
-}
-
-static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
- .bandwidth_update = &dce_virtual_bandwidth_update,
- .vblank_get_counter = &dce_virtual_vblank_get_counter,
- .backlight_set_level = NULL,
- .backlight_get_level = NULL,
- .hpd_sense = &dce_virtual_hpd_sense,
- .hpd_set_polarity = &dce_virtual_hpd_set_polarity,
- .hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
- .page_flip = &dce_virtual_page_flip,
- .page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
- .add_encoder = NULL,
- .add_connector = NULL,
-};
-
-static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
-{
- adev->mode_info.funcs = &dce_virtual_display_funcs;
-}
-
-static int dce_virtual_pageflip(struct amdgpu_device *adev,
- unsigned crtc_id)
-{
- unsigned long flags;
- struct amdgpu_crtc *amdgpu_crtc;
- struct amdgpu_flip_work *works;
-
- amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
-
- if (crtc_id >= adev->mode_info.num_crtc) {
- DRM_ERROR("invalid pageflip crtc %d\n", crtc_id);
- return -EINVAL;
- }
-
- /* IRQ could occur when in initial stage */
- if (amdgpu_crtc == NULL)
- return 0;
-
- spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
- works = amdgpu_crtc->pflip_works;
- if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
- DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
- "AMDGPU_FLIP_SUBMITTED(%d)\n",
- amdgpu_crtc->pflip_status,
- AMDGPU_FLIP_SUBMITTED);
- spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
- return 0;
- }
-
- /* page flip completed. clean up */
- amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
- amdgpu_crtc->pflip_works = NULL;
-
- /* wakeup usersapce */
- if (works->event)
- drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event);
-
- spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
-
- drm_crtc_vblank_put(&amdgpu_crtc->base);
- amdgpu_bo_unref(&works->old_abo);
- kfree(works->shared);
- kfree(works);
-
- return 0;
-}
-
-static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer)
-{
- struct amdgpu_crtc *amdgpu_crtc = container_of(vblank_timer,
- struct amdgpu_crtc, vblank_timer);
- struct drm_device *ddev = amdgpu_crtc->base.dev;
- struct amdgpu_device *adev = drm_to_adev(ddev);
- struct amdgpu_irq_src *source = adev->irq.client[AMDGPU_IRQ_CLIENTID_LEGACY].sources
- [VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER];
- int irq_type = amdgpu_display_crtc_idx_to_irq_type(adev,
- amdgpu_crtc->crtc_id);
-
- if (amdgpu_irq_enabled(adev, source, irq_type)) {
- drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
- dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
- }
- hrtimer_start(vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD,
- HRTIMER_MODE_REL);
-
- return HRTIMER_NORESTART;
-}
-
-static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
- int crtc,
- enum amdgpu_interrupt_state state)
-{
- if (crtc >= adev->mode_info.num_crtc || !adev->mode_info.crtcs[crtc]) {
- DRM_DEBUG("invalid crtc %d\n", crtc);
- return;
- }
-
- adev->mode_info.crtcs[crtc]->vsync_timer_enabled = state;
- DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc, state);
-}
-
-
-static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev,
- struct amdgpu_irq_src *source,
- unsigned type,
- enum amdgpu_interrupt_state state)
-{
- if (type > AMDGPU_CRTC_IRQ_VBLANK6)
- return -EINVAL;
-
- dce_virtual_set_crtc_vblank_interrupt_state(adev, type, state);
-
- return 0;
-}
-
-static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
- .set = dce_virtual_set_crtc_irq_state,
- .process = NULL,
-};
-
-static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
-{
- adev->crtc_irq.num_types = adev->mode_info.num_crtc;
- adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs;
-}
-
const struct amdgpu_ip_block_version dce_virtual_ip_block =
{
.type = AMD_IP_BLOCK_TYPE_DCE,
--
2.32.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3)
2021-07-21 17:07 [PATCH 0/3] drm/amdgpu: modernize virtual display feature Ryan Taylor
2021-07-21 17:07 ` [PATCH 1/3] drm/amdgpu: create amdgpu_vkms (v2) Ryan Taylor
2021-07-21 17:07 ` [PATCH 2/3] drm/amdgpu: cleanup dce_virtual Ryan Taylor
@ 2021-07-21 17:07 ` Ryan Taylor
2021-07-23 14:33 ` Alex Deucher
2 siblings, 1 reply; 13+ messages in thread
From: Ryan Taylor @ 2021-07-21 17:07 UTC (permalink / raw)
To: dri-devel, amd-gfx
Cc: kernel test robot, daniel.vetter, rodrigo.siqueira, Ryan Taylor,
melissa.srw, Alex Deucher
Move dce_virtual into amdgpu_vkms and update all references to
dce_virtual with amdgpu_vkms.
v2: Removed more references to dce_virtual.
v3: Restored display modes from previous implementation.
Reported-by: kernel test robot <lkp@intel.com>
Suggested-by: Alex Deucher <Alexander.Deucher@amd.com>
Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
---
drivers/gpu/drm/amd/amdgpu/Makefile | 3 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 234 ++++++++++++++++++++++-
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 5 +-
drivers/gpu/drm/amd/amdgpu/cik.c | 10 +-
drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 223 ---------------------
drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 30 ---
drivers/gpu/drm/amd/amdgpu/nv.c | 20 +-
drivers/gpu/drm/amd/amdgpu/si.c | 8 +-
drivers/gpu/drm/amd/amdgpu/soc15.c | 10 +-
drivers/gpu/drm/amd/amdgpu/vi.c | 14 +-
10 files changed, 264 insertions(+), 293 deletions(-)
delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.c
delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.h
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index 30cbcd5ce1cc..0d814c957461 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -120,8 +120,7 @@ amdgpu-y += \
amdgpu-y += \
dce_v10_0.o \
dce_v11_0.o \
- amdgpu_vkms.o \
- dce_virtual.o
+ amdgpu_vkms.o
# add GFX block
amdgpu-y += \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
index d5c1f1c58f5f..538d41e6666a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -5,6 +5,15 @@
#include <drm/drm_vblank.h>
#include "amdgpu.h"
+#ifdef CONFIG_DRM_AMDGPU_SI
+#include "dce_v6_0.h"
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
+#include "dce_v8_0.h"
+#endif
+#include "dce_v10_0.h"
+#include "dce_v11_0.h"
+#include "ivsrcid/ivsrcid_vislands30.h"
#include "amdgpu_vkms.h"
#include "amdgpu_display.h"
@@ -180,12 +189,45 @@ static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
{
- int count;
+ struct drm_device *dev = connector->dev;
+ struct drm_display_mode *mode = NULL;
+ unsigned i;
+ static const struct mode_size {
+ int w;
+ int h;
+ } common_modes[] = {
+ { 640, 480},
+ { 720, 480},
+ { 800, 600},
+ { 848, 480},
+ {1024, 768},
+ {1152, 768},
+ {1280, 720},
+ {1280, 800},
+ {1280, 854},
+ {1280, 960},
+ {1280, 1024},
+ {1440, 900},
+ {1400, 1050},
+ {1680, 1050},
+ {1600, 1200},
+ {1920, 1080},
+ {1920, 1200},
+ {2560, 1440},
+ {4096, 3112},
+ {3656, 2664},
+ {3840, 2160},
+ {4096, 2160},
+ };
+
+ for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
+ mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
+ drm_mode_probed_add(connector, mode);
+ }
- count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
- return count;
+ return ARRAY_SIZE(common_modes);
}
static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
@@ -409,3 +451,189 @@ int amdgpu_vkms_output_init(struct drm_device *dev,
return ret;
}
+
+const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = {
+ .fb_create = amdgpu_display_user_framebuffer_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+static int amdgpu_vkms_sw_init(void *handle)
+{
+ int r, i;
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ adev_to_drm(adev)->max_vblank_count = 0;
+
+ adev_to_drm(adev)->mode_config.funcs = &amdgpu_vkms_mode_funcs;
+
+ adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
+ adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
+
+ adev_to_drm(adev)->mode_config.preferred_depth = 24;
+ adev_to_drm(adev)->mode_config.prefer_shadow = 1;
+
+ adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
+
+ r = amdgpu_display_modeset_create_props(adev);
+ if (r)
+ return r;
+
+ adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
+
+ /* allocate crtcs, encoders, connectors */
+ for (i = 0; i < adev->mode_info.num_crtc; i++) {
+ r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
+ if (r)
+ return r;
+ }
+
+ drm_kms_helper_poll_init(adev_to_drm(adev));
+
+ adev->mode_info.mode_config_initialized = true;
+ return 0;
+}
+
+static int amdgpu_vkms_sw_fini(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ int i = 0;
+
+ for (i = 0; i < adev->mode_info.num_crtc; i++)
+ if (adev->mode_info.crtcs[i])
+ hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
+
+ kfree(adev->mode_info.bios_hardcoded_edid);
+ kfree(adev->amdgpu_vkms_output);
+
+ drm_kms_helper_poll_fini(adev_to_drm(adev));
+
+ adev->mode_info.mode_config_initialized = false;
+ return 0;
+}
+
+static int amdgpu_vkms_hw_init(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ switch (adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ case CHIP_OLAND:
+ dce_v6_0_disable_dce(adev);
+ break;
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
+ case CHIP_BONAIRE:
+ case CHIP_HAWAII:
+ case CHIP_KAVERI:
+ case CHIP_KABINI:
+ case CHIP_MULLINS:
+ dce_v8_0_disable_dce(adev);
+ break;
+#endif
+ case CHIP_FIJI:
+ case CHIP_TONGA:
+ dce_v10_0_disable_dce(adev);
+ break;
+ case CHIP_CARRIZO:
+ case CHIP_STONEY:
+ case CHIP_POLARIS10:
+ case CHIP_POLARIS11:
+ case CHIP_VEGAM:
+ dce_v11_0_disable_dce(adev);
+ break;
+ case CHIP_TOPAZ:
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_HAINAN:
+#endif
+ /* no DCE */
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int amdgpu_vkms_hw_fini(void *handle)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_suspend(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ int r;
+
+ r = drm_mode_config_helper_suspend(adev_to_drm(adev));
+ if (r)
+ return r;
+ return amdgpu_vkms_hw_fini(handle);
+}
+
+static int amdgpu_vkms_resume(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ int r;
+
+ r = amdgpu_vkms_hw_init(handle);
+ if (r)
+ return r;
+ return drm_mode_config_helper_resume(adev_to_drm(adev));
+}
+
+static bool amdgpu_vkms_is_idle(void *handle)
+{
+ return true;
+}
+
+static int amdgpu_vkms_wait_for_idle(void *handle)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_soft_reset(void *handle)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_set_clockgating_state(void *handle,
+ enum amd_clockgating_state state)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_set_powergating_state(void *handle,
+ enum amd_powergating_state state)
+{
+ return 0;
+}
+
+static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
+ .name = "amdgpu_vkms",
+ .early_init = NULL,
+ .late_init = NULL,
+ .sw_init = amdgpu_vkms_sw_init,
+ .sw_fini = amdgpu_vkms_sw_fini,
+ .hw_init = amdgpu_vkms_hw_init,
+ .hw_fini = amdgpu_vkms_hw_fini,
+ .suspend = amdgpu_vkms_suspend,
+ .resume = amdgpu_vkms_resume,
+ .is_idle = amdgpu_vkms_is_idle,
+ .wait_for_idle = amdgpu_vkms_wait_for_idle,
+ .soft_reset = amdgpu_vkms_soft_reset,
+ .set_clockgating_state = amdgpu_vkms_set_clockgating_state,
+ .set_powergating_state = amdgpu_vkms_set_powergating_state,
+};
+
+const struct amdgpu_ip_block_version amdgpu_vkms_ip_block =
+{
+ .type = AMD_IP_BLOCK_TYPE_DCE,
+ .major = 1,
+ .minor = 0,
+ .rev = 0,
+ .funcs = &amdgpu_vkms_ip_funcs,
+};
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
index 5dab51fbecf3..97f1b79c0724 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
@@ -4,7 +4,7 @@
#define _AMDGPU_VKMS_H_
#define XRES_DEF 1024
-#define YRES_DEF 764
+#define YRES_DEF 768
#define XRES_MAX 16384
#define YRES_MAX 16384
@@ -23,7 +23,4 @@ struct amdgpu_vkms_output {
struct drm_pending_vblank_event *event;
};
-int amdgpu_vkms_output_init(struct drm_device *dev,
- struct amdgpu_vkms_output *output, int index);
-
#endif /* _AMDGPU_VKMS_H_ */
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index c0fcc41ee574..54f28c075f21 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -70,7 +70,7 @@
#include "amdgpu_dm.h"
#include "amdgpu_amdkfd.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
static const struct amdgpu_video_codec_info cik_video_codecs_encode_array[] =
{
@@ -2259,7 +2259,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2277,7 +2277,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2295,7 +2295,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2315,7 +2315,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
deleted file mode 100644
index 18369b47eac7..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <drm/drm_atomic_helper.h>
-
-#include "amdgpu.h"
-#ifdef CONFIG_DRM_AMDGPU_SI
-#include "dce_v6_0.h"
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
-#include "dce_v8_0.h"
-#endif
-#include "dce_v10_0.h"
-#include "dce_v11_0.h"
-#include "dce_virtual.h"
-#include "ivsrcid/ivsrcid_vislands30.h"
-#include "amdgpu_display.h"
-#include "amdgpu_vkms.h"
-
-const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
- .fb_create = amdgpu_display_user_framebuffer_create,
- .atomic_check = drm_atomic_helper_check,
- .atomic_commit = drm_atomic_helper_commit,
-};
-
-static int dce_virtual_sw_init(void *handle)
-{
- int r, i;
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-
- adev_to_drm(adev)->max_vblank_count = 0;
-
- adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
-
- adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
- adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
-
- adev_to_drm(adev)->mode_config.preferred_depth = 24;
- adev_to_drm(adev)->mode_config.prefer_shadow = 1;
-
- adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
-
- r = amdgpu_display_modeset_create_props(adev);
- if (r)
- return r;
-
- adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
-
- /* allocate crtcs, encoders, connectors */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
- if (r)
- return r;
- }
-
- drm_kms_helper_poll_init(adev_to_drm(adev));
-
- adev->mode_info.mode_config_initialized = true;
- return 0;
-}
-
-static int dce_virtual_sw_fini(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int i = 0;
-
- for (i = 0; i < adev->mode_info.num_crtc; i++)
- if (adev->mode_info.crtcs[i])
- hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
-
- kfree(adev->mode_info.bios_hardcoded_edid);
- kfree(adev->amdgpu_vkms_output);
-
- drm_kms_helper_poll_fini(adev_to_drm(adev));
-
- adev->mode_info.mode_config_initialized = false;
- return 0;
-}
-
-static int dce_virtual_hw_init(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-
- switch (adev->asic_type) {
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_TAHITI:
- case CHIP_PITCAIRN:
- case CHIP_VERDE:
- case CHIP_OLAND:
- dce_v6_0_disable_dce(adev);
- break;
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
- case CHIP_BONAIRE:
- case CHIP_HAWAII:
- case CHIP_KAVERI:
- case CHIP_KABINI:
- case CHIP_MULLINS:
- dce_v8_0_disable_dce(adev);
- break;
-#endif
- case CHIP_FIJI:
- case CHIP_TONGA:
- dce_v10_0_disable_dce(adev);
- break;
- case CHIP_CARRIZO:
- case CHIP_STONEY:
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_VEGAM:
- dce_v11_0_disable_dce(adev);
- break;
- case CHIP_TOPAZ:
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_HAINAN:
-#endif
- /* no DCE */
- break;
- default:
- break;
- }
- return 0;
-}
-
-static int dce_virtual_hw_fini(void *handle)
-{
- return 0;
-}
-
-static int dce_virtual_suspend(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int r;
-
- r = drm_mode_config_helper_suspend(adev_to_drm(adev));
- if (r)
- return r;
- return dce_virtual_hw_fini(handle);
-}
-
-static int dce_virtual_resume(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int r;
-
- r = dce_virtual_hw_init(handle);
- if (r)
- return r;
- return drm_mode_config_helper_resume(adev_to_drm(adev));
-}
-
-static bool dce_virtual_is_idle(void *handle)
-{
- return true;
-}
-
-static int dce_virtual_wait_for_idle(void *handle)
-{
- return 0;
-}
-
-static int dce_virtual_soft_reset(void *handle)
-{
- return 0;
-}
-
-static int dce_virtual_set_clockgating_state(void *handle,
- enum amd_clockgating_state state)
-{
- return 0;
-}
-
-static int dce_virtual_set_powergating_state(void *handle,
- enum amd_powergating_state state)
-{
- return 0;
-}
-
-static const struct amd_ip_funcs dce_virtual_ip_funcs = {
- .name = "dce_virtual",
- .early_init = NULL,
- .late_init = NULL,
- .sw_init = dce_virtual_sw_init,
- .sw_fini = dce_virtual_sw_fini,
- .hw_init = dce_virtual_hw_init,
- .hw_fini = dce_virtual_hw_fini,
- .suspend = dce_virtual_suspend,
- .resume = dce_virtual_resume,
- .is_idle = dce_virtual_is_idle,
- .wait_for_idle = dce_virtual_wait_for_idle,
- .soft_reset = dce_virtual_soft_reset,
- .set_clockgating_state = dce_virtual_set_clockgating_state,
- .set_powergating_state = dce_virtual_set_powergating_state,
-};
-
-const struct amdgpu_ip_block_version dce_virtual_ip_block =
-{
- .type = AMD_IP_BLOCK_TYPE_DCE,
- .major = 1,
- .minor = 0,
- .rev = 0,
- .funcs = &dce_virtual_ip_funcs,
-};
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
deleted file mode 100644
index ed422012c8c6..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef __DCE_VIRTUAL_H__
-#define __DCE_VIRTUAL_H__
-
-extern const struct amdgpu_ip_block_version dce_virtual_ip_block;
-
-#endif
-
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index 436fb13e32f0..696ecc1ccb28 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -58,7 +58,7 @@
#include "jpeg_v2_0.h"
#include "vcn_v3_0.h"
#include "jpeg_v3_0.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "mes_v10_1.h"
#include "mxgpu_nv.h"
#include "smuio_v11_0.h"
@@ -721,7 +721,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
!amdgpu_sriov_vf(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -749,7 +749,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -779,7 +779,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
is_support_sw_smu(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -802,7 +802,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
is_support_sw_smu(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -823,7 +823,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -843,7 +843,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
is_support_sw_smu(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -865,7 +865,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -883,11 +883,11 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 7cbc2bb03bc6..e6d2f74a7976 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -44,7 +44,7 @@
#include "dce_v6_0.h"
#include "si.h"
#include "uvd_v3_1.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "gca/gfx_6_0_d.h"
#include "oss/oss_1_0_d.h"
#include "oss/oss_1_0_sh_mask.h"
@@ -2759,7 +2759,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2777,7 +2777,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2795,7 +2795,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
break;
default:
BUG();
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index a5e085e570f7..f7b56a746c15 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -74,7 +74,7 @@
#include "smuio_v9_0.h"
#include "smuio_v11_0.h"
#include "smuio_v13_0.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "mxgpu_ai.h"
#include "amdgpu_ras.h"
#include "amdgpu_xgmi.h"
@@ -843,7 +843,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
}
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -863,7 +863,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -885,7 +885,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
}
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
@@ -909,7 +909,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 3d21c0799037..fe9a7cc8d9eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -77,7 +77,7 @@
#if defined(CONFIG_DRM_AMD_ACP)
#include "amdgpu_acp.h"
#endif
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "mxgpu_vi.h"
#include "amdgpu_dm.h"
@@ -2102,7 +2102,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v2_4_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
break;
case CHIP_FIJI:
amdgpu_device_ip_block_add(adev, &vi_common_ip_block);
@@ -2112,7 +2112,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2132,7 +2132,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2155,7 +2155,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_1_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2173,7 +2173,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2194,7 +2194,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
--
2.32.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3)
2021-07-21 17:07 ` [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3) Ryan Taylor
@ 2021-07-23 14:33 ` Alex Deucher
2021-07-23 15:50 ` Taylor, Ryan
0 siblings, 1 reply; 13+ messages in thread
From: Alex Deucher @ 2021-07-23 14:33 UTC (permalink / raw)
To: Ryan Taylor
Cc: kernel test robot, Daniel Vetter, Siqueira, Rodrigo,
amd-gfx list, Melissa Wen, Maling list - DRI developers,
Alex Deucher
On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
>
> Move dce_virtual into amdgpu_vkms and update all references to
> dce_virtual with amdgpu_vkms.
>
> v2: Removed more references to dce_virtual.
>
> v3: Restored display modes from previous implementation.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Suggested-by: Alex Deucher <Alexander.Deucher@amd.com>
> Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/Makefile | 3 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 234 ++++++++++++++++++++++-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 5 +-
> drivers/gpu/drm/amd/amdgpu/cik.c | 10 +-
> drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 223 ---------------------
> drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 30 ---
> drivers/gpu/drm/amd/amdgpu/nv.c | 20 +-
> drivers/gpu/drm/amd/amdgpu/si.c | 8 +-
> drivers/gpu/drm/amd/amdgpu/soc15.c | 10 +-
> drivers/gpu/drm/amd/amdgpu/vi.c | 14 +-
> 10 files changed, 264 insertions(+), 293 deletions(-)
> delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.h
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index 30cbcd5ce1cc..0d814c957461 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -120,8 +120,7 @@ amdgpu-y += \
> amdgpu-y += \
> dce_v10_0.o \
> dce_v11_0.o \
> - amdgpu_vkms.o \
> - dce_virtual.o
> + amdgpu_vkms.o
>
> # add GFX block
> amdgpu-y += \
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> index d5c1f1c58f5f..538d41e6666a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> @@ -5,6 +5,15 @@
> #include <drm/drm_vblank.h>
>
> #include "amdgpu.h"
> +#ifdef CONFIG_DRM_AMDGPU_SI
> +#include "dce_v6_0.h"
> +#endif
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> +#include "dce_v8_0.h"
> +#endif
> +#include "dce_v10_0.h"
> +#include "dce_v11_0.h"
> +#include "ivsrcid/ivsrcid_vislands30.h"
> #include "amdgpu_vkms.h"
> #include "amdgpu_display.h"
>
> @@ -180,12 +189,45 @@ static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
>
> static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
> {
> - int count;
> + struct drm_device *dev = connector->dev;
> + struct drm_display_mode *mode = NULL;
> + unsigned i;
> + static const struct mode_size {
> + int w;
> + int h;
> + } common_modes[] = {
> + { 640, 480},
> + { 720, 480},
> + { 800, 600},
> + { 848, 480},
> + {1024, 768},
> + {1152, 768},
> + {1280, 720},
> + {1280, 800},
> + {1280, 854},
> + {1280, 960},
> + {1280, 1024},
> + {1440, 900},
> + {1400, 1050},
> + {1680, 1050},
> + {1600, 1200},
> + {1920, 1080},
> + {1920, 1200},
> + {2560, 1440},
> + {4096, 3112},
> + {3656, 2664},
> + {3840, 2160},
> + {4096, 2160},
> + };
> +
> + for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
> + mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
> + drm_mode_probed_add(connector, mode);
> + }
>
> - count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
>
> - return count;
> + return ARRAY_SIZE(common_modes);
> }
>
> static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> @@ -409,3 +451,189 @@ int amdgpu_vkms_output_init(struct drm_device *dev,
>
> return ret;
> }
> +
> +const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = {
> + .fb_create = amdgpu_display_user_framebuffer_create,
> + .atomic_check = drm_atomic_helper_check,
> + .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static int amdgpu_vkms_sw_init(void *handle)
> +{
> + int r, i;
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +
> + adev_to_drm(adev)->max_vblank_count = 0;
> +
> + adev_to_drm(adev)->mode_config.funcs = &amdgpu_vkms_mode_funcs;
> +
> + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> +
> + adev_to_drm(adev)->mode_config.preferred_depth = 24;
> + adev_to_drm(adev)->mode_config.prefer_shadow = 1;
> +
> + adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
> +
> + r = amdgpu_display_modeset_create_props(adev);
> + if (r)
> + return r;
> +
> + adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
> +
> + /* allocate crtcs, encoders, connectors */
> + for (i = 0; i < adev->mode_info.num_crtc; i++) {
> + r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
> + if (r)
> + return r;
> + }
> +
> + drm_kms_helper_poll_init(adev_to_drm(adev));
> +
> + adev->mode_info.mode_config_initialized = true;
> + return 0;
> +}
> +
> +static int amdgpu_vkms_sw_fini(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> + int i = 0;
> +
> + for (i = 0; i < adev->mode_info.num_crtc; i++)
> + if (adev->mode_info.crtcs[i])
> + hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> +
> + kfree(adev->mode_info.bios_hardcoded_edid);
> + kfree(adev->amdgpu_vkms_output);
> +
> + drm_kms_helper_poll_fini(adev_to_drm(adev));
> +
> + adev->mode_info.mode_config_initialized = false;
> + return 0;
> +}
> +
> +static int amdgpu_vkms_hw_init(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +
> + switch (adev->asic_type) {
> +#ifdef CONFIG_DRM_AMDGPU_SI
> + case CHIP_TAHITI:
> + case CHIP_PITCAIRN:
> + case CHIP_VERDE:
> + case CHIP_OLAND:
> + dce_v6_0_disable_dce(adev);
> + break;
> +#endif
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> + case CHIP_BONAIRE:
> + case CHIP_HAWAII:
> + case CHIP_KAVERI:
> + case CHIP_KABINI:
> + case CHIP_MULLINS:
> + dce_v8_0_disable_dce(adev);
> + break;
> +#endif
> + case CHIP_FIJI:
> + case CHIP_TONGA:
> + dce_v10_0_disable_dce(adev);
> + break;
> + case CHIP_CARRIZO:
> + case CHIP_STONEY:
> + case CHIP_POLARIS10:
> + case CHIP_POLARIS11:
> + case CHIP_VEGAM:
> + dce_v11_0_disable_dce(adev);
> + break;
> + case CHIP_TOPAZ:
> +#ifdef CONFIG_DRM_AMDGPU_SI
> + case CHIP_HAINAN:
> +#endif
> + /* no DCE */
> + break;
> + default:
> + break;
> + }
> + return 0;
> +}
> +
> +static int amdgpu_vkms_hw_fini(void *handle)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_suspend(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> + int r;
> +
> + r = drm_mode_config_helper_suspend(adev_to_drm(adev));
> + if (r)
> + return r;
> + return amdgpu_vkms_hw_fini(handle);
> +}
> +
> +static int amdgpu_vkms_resume(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> + int r;
> +
> + r = amdgpu_vkms_hw_init(handle);
> + if (r)
> + return r;
> + return drm_mode_config_helper_resume(adev_to_drm(adev));
> +}
> +
> +static bool amdgpu_vkms_is_idle(void *handle)
> +{
> + return true;
> +}
> +
> +static int amdgpu_vkms_wait_for_idle(void *handle)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_soft_reset(void *handle)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_set_clockgating_state(void *handle,
> + enum amd_clockgating_state state)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_set_powergating_state(void *handle,
> + enum amd_powergating_state state)
> +{
> + return 0;
> +}
> +
> +static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
> + .name = "amdgpu_vkms",
> + .early_init = NULL,
> + .late_init = NULL,
> + .sw_init = amdgpu_vkms_sw_init,
> + .sw_fini = amdgpu_vkms_sw_fini,
> + .hw_init = amdgpu_vkms_hw_init,
> + .hw_fini = amdgpu_vkms_hw_fini,
> + .suspend = amdgpu_vkms_suspend,
> + .resume = amdgpu_vkms_resume,
> + .is_idle = amdgpu_vkms_is_idle,
> + .wait_for_idle = amdgpu_vkms_wait_for_idle,
> + .soft_reset = amdgpu_vkms_soft_reset,
> + .set_clockgating_state = amdgpu_vkms_set_clockgating_state,
> + .set_powergating_state = amdgpu_vkms_set_powergating_state,
> +};
> +
> +const struct amdgpu_ip_block_version amdgpu_vkms_ip_block =
> +{
> + .type = AMD_IP_BLOCK_TYPE_DCE,
> + .major = 1,
> + .minor = 0,
> + .rev = 0,
> + .funcs = &amdgpu_vkms_ip_funcs,
> +};
> +
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> index 5dab51fbecf3..97f1b79c0724 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> @@ -4,7 +4,7 @@
> #define _AMDGPU_VKMS_H_
>
> #define XRES_DEF 1024
> -#define YRES_DEF 764
> +#define YRES_DEF 768
Squash this fix into the original patch that added this macro.
>
> #define XRES_MAX 16384
> #define YRES_MAX 16384
> @@ -23,7 +23,4 @@ struct amdgpu_vkms_output {
> struct drm_pending_vblank_event *event;
> };
>
> -int amdgpu_vkms_output_init(struct drm_device *dev,
> - struct amdgpu_vkms_output *output, int index);
> -
> #endif /* _AMDGPU_VKMS_H_ */
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
> index c0fcc41ee574..54f28c075f21 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik.c
> @@ -70,7 +70,7 @@
>
> #include "amdgpu_dm.h"
> #include "amdgpu_amdkfd.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
>
> static const struct amdgpu_video_codec_info cik_video_codecs_encode_array[] =
> {
> @@ -2259,7 +2259,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2277,7 +2277,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2295,7 +2295,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2315,7 +2315,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> deleted file mode 100644
> index 18369b47eac7..000000000000
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ /dev/null
> @@ -1,223 +0,0 @@
> -/*
> - * Copyright 2014 Advanced Micro Devices, Inc.
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the "Software"),
> - * to deal in the Software without restriction, including without limitation
> - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> - * and/or sell copies of the Software, and to permit persons to whom the
> - * Software is furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> - * OTHER DEALINGS IN THE SOFTWARE.
> - *
> - */
> -
> -#include <drm/drm_atomic_helper.h>
> -
> -#include "amdgpu.h"
> -#ifdef CONFIG_DRM_AMDGPU_SI
> -#include "dce_v6_0.h"
> -#endif
> -#ifdef CONFIG_DRM_AMDGPU_CIK
> -#include "dce_v8_0.h"
> -#endif
> -#include "dce_v10_0.h"
> -#include "dce_v11_0.h"
> -#include "dce_virtual.h"
> -#include "ivsrcid/ivsrcid_vislands30.h"
> -#include "amdgpu_display.h"
> -#include "amdgpu_vkms.h"
> -
> -const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> - .fb_create = amdgpu_display_user_framebuffer_create,
> - .atomic_check = drm_atomic_helper_check,
> - .atomic_commit = drm_atomic_helper_commit,
> -};
> -
> -static int dce_virtual_sw_init(void *handle)
> -{
> - int r, i;
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> -
> - adev_to_drm(adev)->max_vblank_count = 0;
> -
> - adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
> -
> - adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> - adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> -
> - adev_to_drm(adev)->mode_config.preferred_depth = 24;
> - adev_to_drm(adev)->mode_config.prefer_shadow = 1;
> -
> - adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
> -
> - r = amdgpu_display_modeset_create_props(adev);
> - if (r)
> - return r;
> -
> - adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
> -
> - /* allocate crtcs, encoders, connectors */
> - for (i = 0; i < adev->mode_info.num_crtc; i++) {
> - r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
> - if (r)
> - return r;
> - }
> -
> - drm_kms_helper_poll_init(adev_to_drm(adev));
> -
> - adev->mode_info.mode_config_initialized = true;
> - return 0;
> -}
> -
> -static int dce_virtual_sw_fini(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> - int i = 0;
> -
> - for (i = 0; i < adev->mode_info.num_crtc; i++)
> - if (adev->mode_info.crtcs[i])
> - hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> -
> - kfree(adev->mode_info.bios_hardcoded_edid);
> - kfree(adev->amdgpu_vkms_output);
> -
> - drm_kms_helper_poll_fini(adev_to_drm(adev));
> -
> - adev->mode_info.mode_config_initialized = false;
> - return 0;
> -}
> -
> -static int dce_virtual_hw_init(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> -
> - switch (adev->asic_type) {
> -#ifdef CONFIG_DRM_AMDGPU_SI
> - case CHIP_TAHITI:
> - case CHIP_PITCAIRN:
> - case CHIP_VERDE:
> - case CHIP_OLAND:
> - dce_v6_0_disable_dce(adev);
> - break;
> -#endif
> -#ifdef CONFIG_DRM_AMDGPU_CIK
> - case CHIP_BONAIRE:
> - case CHIP_HAWAII:
> - case CHIP_KAVERI:
> - case CHIP_KABINI:
> - case CHIP_MULLINS:
> - dce_v8_0_disable_dce(adev);
> - break;
> -#endif
> - case CHIP_FIJI:
> - case CHIP_TONGA:
> - dce_v10_0_disable_dce(adev);
> - break;
> - case CHIP_CARRIZO:
> - case CHIP_STONEY:
> - case CHIP_POLARIS10:
> - case CHIP_POLARIS11:
> - case CHIP_VEGAM:
> - dce_v11_0_disable_dce(adev);
> - break;
> - case CHIP_TOPAZ:
> -#ifdef CONFIG_DRM_AMDGPU_SI
> - case CHIP_HAINAN:
> -#endif
> - /* no DCE */
> - break;
> - default:
> - break;
> - }
> - return 0;
> -}
> -
> -static int dce_virtual_hw_fini(void *handle)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_suspend(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> - int r;
> -
> - r = drm_mode_config_helper_suspend(adev_to_drm(adev));
> - if (r)
> - return r;
> - return dce_virtual_hw_fini(handle);
> -}
> -
> -static int dce_virtual_resume(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> - int r;
> -
> - r = dce_virtual_hw_init(handle);
> - if (r)
> - return r;
> - return drm_mode_config_helper_resume(adev_to_drm(adev));
> -}
> -
> -static bool dce_virtual_is_idle(void *handle)
> -{
> - return true;
> -}
> -
> -static int dce_virtual_wait_for_idle(void *handle)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_soft_reset(void *handle)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_set_clockgating_state(void *handle,
> - enum amd_clockgating_state state)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_set_powergating_state(void *handle,
> - enum amd_powergating_state state)
> -{
> - return 0;
> -}
> -
> -static const struct amd_ip_funcs dce_virtual_ip_funcs = {
> - .name = "dce_virtual",
> - .early_init = NULL,
> - .late_init = NULL,
> - .sw_init = dce_virtual_sw_init,
> - .sw_fini = dce_virtual_sw_fini,
> - .hw_init = dce_virtual_hw_init,
> - .hw_fini = dce_virtual_hw_fini,
> - .suspend = dce_virtual_suspend,
> - .resume = dce_virtual_resume,
> - .is_idle = dce_virtual_is_idle,
> - .wait_for_idle = dce_virtual_wait_for_idle,
> - .soft_reset = dce_virtual_soft_reset,
> - .set_clockgating_state = dce_virtual_set_clockgating_state,
> - .set_powergating_state = dce_virtual_set_powergating_state,
> -};
> -
> -const struct amdgpu_ip_block_version dce_virtual_ip_block =
> -{
> - .type = AMD_IP_BLOCK_TYPE_DCE,
> - .major = 1,
> - .minor = 0,
> - .rev = 0,
> - .funcs = &dce_virtual_ip_funcs,
> -};
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
> deleted file mode 100644
> index ed422012c8c6..000000000000
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/*
> - * Copyright 2014 Advanced Micro Devices, Inc.
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the "Software"),
> - * to deal in the Software without restriction, including without limitation
> - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> - * and/or sell copies of the Software, and to permit persons to whom the
> - * Software is furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> - * OTHER DEALINGS IN THE SOFTWARE.
> - *
> - */
> -
> -#ifndef __DCE_VIRTUAL_H__
> -#define __DCE_VIRTUAL_H__
> -
> -extern const struct amdgpu_ip_block_version dce_virtual_ip_block;
> -
> -#endif
> -
> diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
> index 436fb13e32f0..696ecc1ccb28 100644
> --- a/drivers/gpu/drm/amd/amdgpu/nv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/nv.c
> @@ -58,7 +58,7 @@
> #include "jpeg_v2_0.h"
> #include "vcn_v3_0.h"
> #include "jpeg_v3_0.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "mes_v10_1.h"
> #include "mxgpu_nv.h"
> #include "smuio_v11_0.h"
> @@ -721,7 +721,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> !amdgpu_sriov_vf(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -749,7 +749,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -779,7 +779,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> is_support_sw_smu(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -802,7 +802,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> is_support_sw_smu(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -823,7 +823,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -843,7 +843,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> is_support_sw_smu(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -865,7 +865,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -883,11 +883,11 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
> amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
> index 7cbc2bb03bc6..e6d2f74a7976 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si.c
> @@ -44,7 +44,7 @@
> #include "dce_v6_0.h"
> #include "si.h"
> #include "uvd_v3_1.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "gca/gfx_6_0_d.h"
> #include "oss/oss_1_0_d.h"
> #include "oss/oss_1_0_sh_mask.h"
> @@ -2759,7 +2759,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
> amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2777,7 +2777,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
> amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2795,7 +2795,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
> amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> break;
> default:
> BUG();
> diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
> index a5e085e570f7..f7b56a746c15 100644
> --- a/drivers/gpu/drm/amd/amdgpu/soc15.c
> +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
> @@ -74,7 +74,7 @@
> #include "smuio_v9_0.h"
> #include "smuio_v11_0.h"
> #include "smuio_v13_0.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "mxgpu_ai.h"
> #include "amdgpu_ras.h"
> #include "amdgpu_xgmi.h"
> @@ -843,7 +843,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> }
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -863,7 +863,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -885,7 +885,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> }
>
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> @@ -909,7 +909,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
> index 3d21c0799037..fe9a7cc8d9eb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> @@ -77,7 +77,7 @@
> #if defined(CONFIG_DRM_AMD_ACP)
> #include "amdgpu_acp.h"
> #endif
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "mxgpu_vi.h"
> #include "amdgpu_dm.h"
>
> @@ -2102,7 +2102,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v2_4_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> break;
> case CHIP_FIJI:
> amdgpu_device_ip_block_add(adev, &vi_common_ip_block);
> @@ -2112,7 +2112,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2132,7 +2132,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2155,7 +2155,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_1_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2173,7 +2173,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2194,7 +2194,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> --
> 2.32.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3)
2021-07-23 14:33 ` Alex Deucher
@ 2021-07-23 15:50 ` Taylor, Ryan
0 siblings, 0 replies; 13+ messages in thread
From: Taylor, Ryan @ 2021-07-23 15:50 UTC (permalink / raw)
To: Alex Deucher
Cc: kernel test robot, Daniel Vetter, Siqueira, Rodrigo,
amd-gfx list, Melissa Wen, Maling list - DRI developers, Deucher,
Alexander
[-- Attachment #1: Type: text/plain, Size: 38691 bytes --]
[AMD Official Use Only]
Thanks Alex! I will make these changes.
Best,
Ryan
________________________________
From: Alex Deucher <alexdeucher@gmail.com>
Sent: Friday, July 23, 2021 7:33 AM
To: Taylor, Ryan <Ryan.Taylor@amd.com>
Cc: Maling list - DRI developers <dri-devel@lists.freedesktop.org>; amd-gfx list <amd-gfx@lists.freedesktop.org>; kernel test robot <lkp@intel.com>; Daniel Vetter <daniel.vetter@ffwll.ch>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; Melissa Wen <melissa.srw@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Subject: Re: [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3)
On Wed, Jul 21, 2021 at 1:07 PM Ryan Taylor <Ryan.Taylor@amd.com> wrote:
>
> Move dce_virtual into amdgpu_vkms and update all references to
> dce_virtual with amdgpu_vkms.
>
> v2: Removed more references to dce_virtual.
>
> v3: Restored display modes from previous implementation.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Suggested-by: Alex Deucher <Alexander.Deucher@amd.com>
> Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/Makefile | 3 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 234 ++++++++++++++++++++++-
> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 5 +-
> drivers/gpu/drm/amd/amdgpu/cik.c | 10 +-
> drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 223 ---------------------
> drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 30 ---
> drivers/gpu/drm/amd/amdgpu/nv.c | 20 +-
> drivers/gpu/drm/amd/amdgpu/si.c | 8 +-
> drivers/gpu/drm/amd/amdgpu/soc15.c | 10 +-
> drivers/gpu/drm/amd/amdgpu/vi.c | 14 +-
> 10 files changed, 264 insertions(+), 293 deletions(-)
> delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.h
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index 30cbcd5ce1cc..0d814c957461 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -120,8 +120,7 @@ amdgpu-y += \
> amdgpu-y += \
> dce_v10_0.o \
> dce_v11_0.o \
> - amdgpu_vkms.o \
> - dce_virtual.o
> + amdgpu_vkms.o
>
> # add GFX block
> amdgpu-y += \
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> index d5c1f1c58f5f..538d41e6666a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> @@ -5,6 +5,15 @@
> #include <drm/drm_vblank.h>
>
> #include "amdgpu.h"
> +#ifdef CONFIG_DRM_AMDGPU_SI
> +#include "dce_v6_0.h"
> +#endif
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> +#include "dce_v8_0.h"
> +#endif
> +#include "dce_v10_0.h"
> +#include "dce_v11_0.h"
> +#include "ivsrcid/ivsrcid_vislands30.h"
> #include "amdgpu_vkms.h"
> #include "amdgpu_display.h"
>
> @@ -180,12 +189,45 @@ static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
>
> static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
> {
> - int count;
> + struct drm_device *dev = connector->dev;
> + struct drm_display_mode *mode = NULL;
> + unsigned i;
> + static const struct mode_size {
> + int w;
> + int h;
> + } common_modes[] = {
> + { 640, 480},
> + { 720, 480},
> + { 800, 600},
> + { 848, 480},
> + {1024, 768},
> + {1152, 768},
> + {1280, 720},
> + {1280, 800},
> + {1280, 854},
> + {1280, 960},
> + {1280, 1024},
> + {1440, 900},
> + {1400, 1050},
> + {1680, 1050},
> + {1600, 1200},
> + {1920, 1080},
> + {1920, 1200},
> + {2560, 1440},
> + {4096, 3112},
> + {3656, 2664},
> + {3840, 2160},
> + {4096, 2160},
> + };
> +
> + for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
> + mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
> + drm_mode_probed_add(connector, mode);
> + }
>
> - count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
>
> - return count;
> + return ARRAY_SIZE(common_modes);
> }
>
> static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
> @@ -409,3 +451,189 @@ int amdgpu_vkms_output_init(struct drm_device *dev,
>
> return ret;
> }
> +
> +const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = {
> + .fb_create = amdgpu_display_user_framebuffer_create,
> + .atomic_check = drm_atomic_helper_check,
> + .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static int amdgpu_vkms_sw_init(void *handle)
> +{
> + int r, i;
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +
> + adev_to_drm(adev)->max_vblank_count = 0;
> +
> + adev_to_drm(adev)->mode_config.funcs = &amdgpu_vkms_mode_funcs;
> +
> + adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> + adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> +
> + adev_to_drm(adev)->mode_config.preferred_depth = 24;
> + adev_to_drm(adev)->mode_config.prefer_shadow = 1;
> +
> + adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
> +
> + r = amdgpu_display_modeset_create_props(adev);
> + if (r)
> + return r;
> +
> + adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
> +
> + /* allocate crtcs, encoders, connectors */
> + for (i = 0; i < adev->mode_info.num_crtc; i++) {
> + r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
> + if (r)
> + return r;
> + }
> +
> + drm_kms_helper_poll_init(adev_to_drm(adev));
> +
> + adev->mode_info.mode_config_initialized = true;
> + return 0;
> +}
> +
> +static int amdgpu_vkms_sw_fini(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> + int i = 0;
> +
> + for (i = 0; i < adev->mode_info.num_crtc; i++)
> + if (adev->mode_info.crtcs[i])
> + hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> +
> + kfree(adev->mode_info.bios_hardcoded_edid);
> + kfree(adev->amdgpu_vkms_output);
> +
> + drm_kms_helper_poll_fini(adev_to_drm(adev));
> +
> + adev->mode_info.mode_config_initialized = false;
> + return 0;
> +}
> +
> +static int amdgpu_vkms_hw_init(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +
> + switch (adev->asic_type) {
> +#ifdef CONFIG_DRM_AMDGPU_SI
> + case CHIP_TAHITI:
> + case CHIP_PITCAIRN:
> + case CHIP_VERDE:
> + case CHIP_OLAND:
> + dce_v6_0_disable_dce(adev);
> + break;
> +#endif
> +#ifdef CONFIG_DRM_AMDGPU_CIK
> + case CHIP_BONAIRE:
> + case CHIP_HAWAII:
> + case CHIP_KAVERI:
> + case CHIP_KABINI:
> + case CHIP_MULLINS:
> + dce_v8_0_disable_dce(adev);
> + break;
> +#endif
> + case CHIP_FIJI:
> + case CHIP_TONGA:
> + dce_v10_0_disable_dce(adev);
> + break;
> + case CHIP_CARRIZO:
> + case CHIP_STONEY:
> + case CHIP_POLARIS10:
> + case CHIP_POLARIS11:
> + case CHIP_VEGAM:
> + dce_v11_0_disable_dce(adev);
> + break;
> + case CHIP_TOPAZ:
> +#ifdef CONFIG_DRM_AMDGPU_SI
> + case CHIP_HAINAN:
> +#endif
> + /* no DCE */
> + break;
> + default:
> + break;
> + }
> + return 0;
> +}
> +
> +static int amdgpu_vkms_hw_fini(void *handle)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_suspend(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> + int r;
> +
> + r = drm_mode_config_helper_suspend(adev_to_drm(adev));
> + if (r)
> + return r;
> + return amdgpu_vkms_hw_fini(handle);
> +}
> +
> +static int amdgpu_vkms_resume(void *handle)
> +{
> + struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> + int r;
> +
> + r = amdgpu_vkms_hw_init(handle);
> + if (r)
> + return r;
> + return drm_mode_config_helper_resume(adev_to_drm(adev));
> +}
> +
> +static bool amdgpu_vkms_is_idle(void *handle)
> +{
> + return true;
> +}
> +
> +static int amdgpu_vkms_wait_for_idle(void *handle)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_soft_reset(void *handle)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_set_clockgating_state(void *handle,
> + enum amd_clockgating_state state)
> +{
> + return 0;
> +}
> +
> +static int amdgpu_vkms_set_powergating_state(void *handle,
> + enum amd_powergating_state state)
> +{
> + return 0;
> +}
> +
> +static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
> + .name = "amdgpu_vkms",
> + .early_init = NULL,
> + .late_init = NULL,
> + .sw_init = amdgpu_vkms_sw_init,
> + .sw_fini = amdgpu_vkms_sw_fini,
> + .hw_init = amdgpu_vkms_hw_init,
> + .hw_fini = amdgpu_vkms_hw_fini,
> + .suspend = amdgpu_vkms_suspend,
> + .resume = amdgpu_vkms_resume,
> + .is_idle = amdgpu_vkms_is_idle,
> + .wait_for_idle = amdgpu_vkms_wait_for_idle,
> + .soft_reset = amdgpu_vkms_soft_reset,
> + .set_clockgating_state = amdgpu_vkms_set_clockgating_state,
> + .set_powergating_state = amdgpu_vkms_set_powergating_state,
> +};
> +
> +const struct amdgpu_ip_block_version amdgpu_vkms_ip_block =
> +{
> + .type = AMD_IP_BLOCK_TYPE_DCE,
> + .major = 1,
> + .minor = 0,
> + .rev = 0,
> + .funcs = &amdgpu_vkms_ip_funcs,
> +};
> +
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> index 5dab51fbecf3..97f1b79c0724 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
> @@ -4,7 +4,7 @@
> #define _AMDGPU_VKMS_H_
>
> #define XRES_DEF 1024
> -#define YRES_DEF 764
> +#define YRES_DEF 768
Squash this fix into the original patch that added this macro.
>
> #define XRES_MAX 16384
> #define YRES_MAX 16384
> @@ -23,7 +23,4 @@ struct amdgpu_vkms_output {
> struct drm_pending_vblank_event *event;
> };
>
> -int amdgpu_vkms_output_init(struct drm_device *dev,
> - struct amdgpu_vkms_output *output, int index);
> -
> #endif /* _AMDGPU_VKMS_H_ */
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
> index c0fcc41ee574..54f28c075f21 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik.c
> @@ -70,7 +70,7 @@
>
> #include "amdgpu_dm.h"
> #include "amdgpu_amdkfd.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
>
> static const struct amdgpu_video_codec_info cik_video_codecs_encode_array[] =
> {
> @@ -2259,7 +2259,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2277,7 +2277,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2295,7 +2295,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2315,7 +2315,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
> amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> deleted file mode 100644
> index 18369b47eac7..000000000000
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ /dev/null
> @@ -1,223 +0,0 @@
> -/*
> - * Copyright 2014 Advanced Micro Devices, Inc.
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the "Software"),
> - * to deal in the Software without restriction, including without limitation
> - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> - * and/or sell copies of the Software, and to permit persons to whom the
> - * Software is furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> - * OTHER DEALINGS IN THE SOFTWARE.
> - *
> - */
> -
> -#include <drm/drm_atomic_helper.h>
> -
> -#include "amdgpu.h"
> -#ifdef CONFIG_DRM_AMDGPU_SI
> -#include "dce_v6_0.h"
> -#endif
> -#ifdef CONFIG_DRM_AMDGPU_CIK
> -#include "dce_v8_0.h"
> -#endif
> -#include "dce_v10_0.h"
> -#include "dce_v11_0.h"
> -#include "dce_virtual.h"
> -#include "ivsrcid/ivsrcid_vislands30.h"
> -#include "amdgpu_display.h"
> -#include "amdgpu_vkms.h"
> -
> -const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
> - .fb_create = amdgpu_display_user_framebuffer_create,
> - .atomic_check = drm_atomic_helper_check,
> - .atomic_commit = drm_atomic_helper_commit,
> -};
> -
> -static int dce_virtual_sw_init(void *handle)
> -{
> - int r, i;
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> -
> - adev_to_drm(adev)->max_vblank_count = 0;
> -
> - adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
> -
> - adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
> - adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
> -
> - adev_to_drm(adev)->mode_config.preferred_depth = 24;
> - adev_to_drm(adev)->mode_config.prefer_shadow = 1;
> -
> - adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
> -
> - r = amdgpu_display_modeset_create_props(adev);
> - if (r)
> - return r;
> -
> - adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL);
> -
> - /* allocate crtcs, encoders, connectors */
> - for (i = 0; i < adev->mode_info.num_crtc; i++) {
> - r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
> - if (r)
> - return r;
> - }
> -
> - drm_kms_helper_poll_init(adev_to_drm(adev));
> -
> - adev->mode_info.mode_config_initialized = true;
> - return 0;
> -}
> -
> -static int dce_virtual_sw_fini(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> - int i = 0;
> -
> - for (i = 0; i < adev->mode_info.num_crtc; i++)
> - if (adev->mode_info.crtcs[i])
> - hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
> -
> - kfree(adev->mode_info.bios_hardcoded_edid);
> - kfree(adev->amdgpu_vkms_output);
> -
> - drm_kms_helper_poll_fini(adev_to_drm(adev));
> -
> - adev->mode_info.mode_config_initialized = false;
> - return 0;
> -}
> -
> -static int dce_virtual_hw_init(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> -
> - switch (adev->asic_type) {
> -#ifdef CONFIG_DRM_AMDGPU_SI
> - case CHIP_TAHITI:
> - case CHIP_PITCAIRN:
> - case CHIP_VERDE:
> - case CHIP_OLAND:
> - dce_v6_0_disable_dce(adev);
> - break;
> -#endif
> -#ifdef CONFIG_DRM_AMDGPU_CIK
> - case CHIP_BONAIRE:
> - case CHIP_HAWAII:
> - case CHIP_KAVERI:
> - case CHIP_KABINI:
> - case CHIP_MULLINS:
> - dce_v8_0_disable_dce(adev);
> - break;
> -#endif
> - case CHIP_FIJI:
> - case CHIP_TONGA:
> - dce_v10_0_disable_dce(adev);
> - break;
> - case CHIP_CARRIZO:
> - case CHIP_STONEY:
> - case CHIP_POLARIS10:
> - case CHIP_POLARIS11:
> - case CHIP_VEGAM:
> - dce_v11_0_disable_dce(adev);
> - break;
> - case CHIP_TOPAZ:
> -#ifdef CONFIG_DRM_AMDGPU_SI
> - case CHIP_HAINAN:
> -#endif
> - /* no DCE */
> - break;
> - default:
> - break;
> - }
> - return 0;
> -}
> -
> -static int dce_virtual_hw_fini(void *handle)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_suspend(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> - int r;
> -
> - r = drm_mode_config_helper_suspend(adev_to_drm(adev));
> - if (r)
> - return r;
> - return dce_virtual_hw_fini(handle);
> -}
> -
> -static int dce_virtual_resume(void *handle)
> -{
> - struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> - int r;
> -
> - r = dce_virtual_hw_init(handle);
> - if (r)
> - return r;
> - return drm_mode_config_helper_resume(adev_to_drm(adev));
> -}
> -
> -static bool dce_virtual_is_idle(void *handle)
> -{
> - return true;
> -}
> -
> -static int dce_virtual_wait_for_idle(void *handle)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_soft_reset(void *handle)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_set_clockgating_state(void *handle,
> - enum amd_clockgating_state state)
> -{
> - return 0;
> -}
> -
> -static int dce_virtual_set_powergating_state(void *handle,
> - enum amd_powergating_state state)
> -{
> - return 0;
> -}
> -
> -static const struct amd_ip_funcs dce_virtual_ip_funcs = {
> - .name = "dce_virtual",
> - .early_init = NULL,
> - .late_init = NULL,
> - .sw_init = dce_virtual_sw_init,
> - .sw_fini = dce_virtual_sw_fini,
> - .hw_init = dce_virtual_hw_init,
> - .hw_fini = dce_virtual_hw_fini,
> - .suspend = dce_virtual_suspend,
> - .resume = dce_virtual_resume,
> - .is_idle = dce_virtual_is_idle,
> - .wait_for_idle = dce_virtual_wait_for_idle,
> - .soft_reset = dce_virtual_soft_reset,
> - .set_clockgating_state = dce_virtual_set_clockgating_state,
> - .set_powergating_state = dce_virtual_set_powergating_state,
> -};
> -
> -const struct amdgpu_ip_block_version dce_virtual_ip_block =
> -{
> - .type = AMD_IP_BLOCK_TYPE_DCE,
> - .major = 1,
> - .minor = 0,
> - .rev = 0,
> - .funcs = &dce_virtual_ip_funcs,
> -};
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
> deleted file mode 100644
> index ed422012c8c6..000000000000
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/*
> - * Copyright 2014 Advanced Micro Devices, Inc.
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the "Software"),
> - * to deal in the Software without restriction, including without limitation
> - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> - * and/or sell copies of the Software, and to permit persons to whom the
> - * Software is furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> - * OTHER DEALINGS IN THE SOFTWARE.
> - *
> - */
> -
> -#ifndef __DCE_VIRTUAL_H__
> -#define __DCE_VIRTUAL_H__
> -
> -extern const struct amdgpu_ip_block_version dce_virtual_ip_block;
> -
> -#endif
> -
> diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
> index 436fb13e32f0..696ecc1ccb28 100644
> --- a/drivers/gpu/drm/amd/amdgpu/nv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/nv.c
> @@ -58,7 +58,7 @@
> #include "jpeg_v2_0.h"
> #include "vcn_v3_0.h"
> #include "jpeg_v3_0.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "mes_v10_1.h"
> #include "mxgpu_nv.h"
> #include "smuio_v11_0.h"
> @@ -721,7 +721,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> !amdgpu_sriov_vf(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -749,7 +749,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -779,7 +779,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> is_support_sw_smu(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -802,7 +802,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> is_support_sw_smu(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -823,7 +823,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -843,7 +843,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> is_support_sw_smu(adev))
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -865,7 +865,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -883,11 +883,11 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
> amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
> index 7cbc2bb03bc6..e6d2f74a7976 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si.c
> @@ -44,7 +44,7 @@
> #include "dce_v6_0.h"
> #include "si.h"
> #include "uvd_v3_1.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "gca/gfx_6_0_d.h"
> #include "oss/oss_1_0_d.h"
> #include "oss/oss_1_0_sh_mask.h"
> @@ -2759,7 +2759,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
> amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2777,7 +2777,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
> amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2795,7 +2795,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
> amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> break;
> default:
> BUG();
> diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
> index a5e085e570f7..f7b56a746c15 100644
> --- a/drivers/gpu/drm/amd/amdgpu/soc15.c
> +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
> @@ -74,7 +74,7 @@
> #include "smuio_v9_0.h"
> #include "smuio_v11_0.h"
> #include "smuio_v13_0.h"
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "mxgpu_ai.h"
> #include "amdgpu_ras.h"
> #include "amdgpu_xgmi.h"
> @@ -843,7 +843,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> }
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -863,7 +863,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -885,7 +885,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> }
>
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> @@ -909,7 +909,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
> amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
> index 3d21c0799037..fe9a7cc8d9eb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> @@ -77,7 +77,7 @@
> #if defined(CONFIG_DRM_AMD_ACP)
> #include "amdgpu_acp.h"
> #endif
> -#include "dce_virtual.h"
> +#include "amdgpu_vkms.h"
> #include "mxgpu_vi.h"
> #include "amdgpu_dm.h"
>
> @@ -2102,7 +2102,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v2_4_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> break;
> case CHIP_FIJI:
> amdgpu_device_ip_block_add(adev, &vi_common_ip_block);
> @@ -2112,7 +2112,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2132,7 +2132,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2155,7 +2155,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_1_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2173,7 +2173,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> @@ -2194,7 +2194,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
> amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
> amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> if (adev->enable_virtual_display)
> - amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
> #if defined(CONFIG_DRM_AMD_DC)
> else if (amdgpu_device_has_dc_support(adev))
> amdgpu_device_ip_block_add(adev, &dm_ip_block);
> --
> 2.32.0
>
[-- Attachment #2: Type: text/html, Size: 77181 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms (v3)
2021-07-28 0:11 [PATCH 0/3] drm/amdgpu: modernize virtual display feature Ryan Taylor
@ 2021-07-28 0:11 ` Ryan Taylor
0 siblings, 0 replies; 13+ messages in thread
From: Ryan Taylor @ 2021-07-28 0:11 UTC (permalink / raw)
To: dri-devel, amd-gfx
Cc: kernel test robot, daniel.vetter, rodrigo.siqueira, Ryan Taylor,
melissa.srw, Alex Deucher
Move dce_virtual into amdgpu_vkms and update all references to
dce_virtual with amdgpu_vkms.
v2: Removed more references to dce_virtual.
v3: Restored display modes from previous implementation.
Reported-by: kernel test robot <lkp@intel.com>
Suggested-by: Alex Deucher <Alexander.Deucher@amd.com>
Signed-off-by: Ryan Taylor <Ryan.Taylor@amd.com>
---
drivers/gpu/drm/amd/amdgpu/Makefile | 3 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 195 ++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 3 -
drivers/gpu/drm/amd/amdgpu/cik.c | 10 +-
drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 223 -----------------------
drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 30 ---
drivers/gpu/drm/amd/amdgpu/nv.c | 22 +--
drivers/gpu/drm/amd/amdgpu/si.c | 8 +-
drivers/gpu/drm/amd/amdgpu/soc15.c | 10 +-
drivers/gpu/drm/amd/amdgpu/vi.c | 14 +-
10 files changed, 228 insertions(+), 290 deletions(-)
delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.c
delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.h
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index 30cbcd5ce1cc..0d814c957461 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -120,8 +120,7 @@ amdgpu-y += \
amdgpu-y += \
dce_v10_0.o \
dce_v11_0.o \
- amdgpu_vkms.o \
- dce_virtual.o
+ amdgpu_vkms.o
# add GFX block
amdgpu-y += \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
index e2810b22bb43..50bdc39733aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -5,6 +5,15 @@
#include <drm/drm_vblank.h>
#include "amdgpu.h"
+#ifdef CONFIG_DRM_AMDGPU_SI
+#include "dce_v6_0.h"
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
+#include "dce_v8_0.h"
+#endif
+#include "dce_v10_0.h"
+#include "dce_v11_0.h"
+#include "ivsrcid/ivsrcid_vislands30.h"
#include "amdgpu_vkms.h"
#include "amdgpu_display.h"
@@ -444,3 +453,189 @@ int amdgpu_vkms_output_init(struct drm_device *dev,
return ret;
}
+
+const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = {
+ .fb_create = amdgpu_display_user_framebuffer_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+static int amdgpu_vkms_sw_init(void *handle)
+{
+ int r, i;
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ adev_to_drm(adev)->max_vblank_count = 0;
+
+ adev_to_drm(adev)->mode_config.funcs = &amdgpu_vkms_mode_funcs;
+
+ adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
+ adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
+
+ adev_to_drm(adev)->mode_config.preferred_depth = 24;
+ adev_to_drm(adev)->mode_config.prefer_shadow = 1;
+
+ adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
+
+ r = amdgpu_display_modeset_create_props(adev);
+ if (r)
+ return r;
+
+ adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc, sizeof(struct amdgpu_vkms_output), GFP_KERNEL);
+
+ /* allocate crtcs, encoders, connectors */
+ for (i = 0; i < adev->mode_info.num_crtc; i++) {
+ r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
+ if (r)
+ return r;
+ }
+
+ drm_kms_helper_poll_init(adev_to_drm(adev));
+
+ adev->mode_info.mode_config_initialized = true;
+ return 0;
+}
+
+static int amdgpu_vkms_sw_fini(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ int i = 0;
+
+ for (i = 0; i < adev->mode_info.num_crtc; i++)
+ if (adev->mode_info.crtcs[i])
+ hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
+
+ kfree(adev->mode_info.bios_hardcoded_edid);
+ kfree(adev->amdgpu_vkms_output);
+
+ drm_kms_helper_poll_fini(adev_to_drm(adev));
+
+ adev->mode_info.mode_config_initialized = false;
+ return 0;
+}
+
+static int amdgpu_vkms_hw_init(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ switch (adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ case CHIP_OLAND:
+ dce_v6_0_disable_dce(adev);
+ break;
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
+ case CHIP_BONAIRE:
+ case CHIP_HAWAII:
+ case CHIP_KAVERI:
+ case CHIP_KABINI:
+ case CHIP_MULLINS:
+ dce_v8_0_disable_dce(adev);
+ break;
+#endif
+ case CHIP_FIJI:
+ case CHIP_TONGA:
+ dce_v10_0_disable_dce(adev);
+ break;
+ case CHIP_CARRIZO:
+ case CHIP_STONEY:
+ case CHIP_POLARIS10:
+ case CHIP_POLARIS11:
+ case CHIP_VEGAM:
+ dce_v11_0_disable_dce(adev);
+ break;
+ case CHIP_TOPAZ:
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_HAINAN:
+#endif
+ /* no DCE */
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int amdgpu_vkms_hw_fini(void *handle)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_suspend(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ int r;
+
+ r = drm_mode_config_helper_suspend(adev_to_drm(adev));
+ if (r)
+ return r;
+ return amdgpu_vkms_hw_fini(handle);
+}
+
+static int amdgpu_vkms_resume(void *handle)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ int r;
+
+ r = amdgpu_vkms_hw_init(handle);
+ if (r)
+ return r;
+ return drm_mode_config_helper_resume(adev_to_drm(adev));
+}
+
+static bool amdgpu_vkms_is_idle(void *handle)
+{
+ return true;
+}
+
+static int amdgpu_vkms_wait_for_idle(void *handle)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_soft_reset(void *handle)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_set_clockgating_state(void *handle,
+ enum amd_clockgating_state state)
+{
+ return 0;
+}
+
+static int amdgpu_vkms_set_powergating_state(void *handle,
+ enum amd_powergating_state state)
+{
+ return 0;
+}
+
+static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
+ .name = "amdgpu_vkms",
+ .early_init = NULL,
+ .late_init = NULL,
+ .sw_init = amdgpu_vkms_sw_init,
+ .sw_fini = amdgpu_vkms_sw_fini,
+ .hw_init = amdgpu_vkms_hw_init,
+ .hw_fini = amdgpu_vkms_hw_fini,
+ .suspend = amdgpu_vkms_suspend,
+ .resume = amdgpu_vkms_resume,
+ .is_idle = amdgpu_vkms_is_idle,
+ .wait_for_idle = amdgpu_vkms_wait_for_idle,
+ .soft_reset = amdgpu_vkms_soft_reset,
+ .set_clockgating_state = amdgpu_vkms_set_clockgating_state,
+ .set_powergating_state = amdgpu_vkms_set_powergating_state,
+};
+
+const struct amdgpu_ip_block_version amdgpu_vkms_ip_block =
+{
+ .type = AMD_IP_BLOCK_TYPE_DCE,
+ .major = 1,
+ .minor = 0,
+ .rev = 0,
+ .funcs = &amdgpu_vkms_ip_funcs,
+};
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
index 251881b60048..97f1b79c0724 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
@@ -23,7 +23,4 @@ struct amdgpu_vkms_output {
struct drm_pending_vblank_event *event;
};
-int amdgpu_vkms_output_init(struct drm_device *dev,
- struct amdgpu_vkms_output *output, int index);
-
#endif /* _AMDGPU_VKMS_H_ */
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index c0fcc41ee574..54f28c075f21 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -70,7 +70,7 @@
#include "amdgpu_dm.h"
#include "amdgpu_amdkfd.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
static const struct amdgpu_video_codec_info cik_video_codecs_encode_array[] =
{
@@ -2259,7 +2259,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2277,7 +2277,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2295,7 +2295,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2315,7 +2315,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
deleted file mode 100644
index 4d7069b2d0f9..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <drm/drm_atomic_helper.h>
-
-#include "amdgpu.h"
-#ifdef CONFIG_DRM_AMDGPU_SI
-#include "dce_v6_0.h"
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
-#include "dce_v8_0.h"
-#endif
-#include "dce_v10_0.h"
-#include "dce_v11_0.h"
-#include "dce_virtual.h"
-#include "ivsrcid/ivsrcid_vislands30.h"
-#include "amdgpu_display.h"
-#include "amdgpu_vkms.h"
-
-const struct drm_mode_config_funcs dce_virtual_mode_funcs = {
- .fb_create = amdgpu_display_user_framebuffer_create,
- .atomic_check = drm_atomic_helper_check,
- .atomic_commit = drm_atomic_helper_commit,
-};
-
-static int dce_virtual_sw_init(void *handle)
-{
- int r, i;
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-
- adev_to_drm(adev)->max_vblank_count = 0;
-
- adev_to_drm(adev)->mode_config.funcs = &dce_virtual_mode_funcs;
-
- adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
- adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
-
- adev_to_drm(adev)->mode_config.preferred_depth = 24;
- adev_to_drm(adev)->mode_config.prefer_shadow = 1;
-
- adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
-
- r = amdgpu_display_modeset_create_props(adev);
- if (r)
- return r;
-
- adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc, sizeof(struct amdgpu_vkms_output), GFP_KERNEL);
-
- /* allocate crtcs, encoders, connectors */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
- if (r)
- return r;
- }
-
- drm_kms_helper_poll_init(adev_to_drm(adev));
-
- adev->mode_info.mode_config_initialized = true;
- return 0;
-}
-
-static int dce_virtual_sw_fini(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int i = 0;
-
- for (i = 0; i < adev->mode_info.num_crtc; i++)
- if (adev->mode_info.crtcs[i])
- hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
-
- kfree(adev->mode_info.bios_hardcoded_edid);
- kfree(adev->amdgpu_vkms_output);
-
- drm_kms_helper_poll_fini(adev_to_drm(adev));
-
- adev->mode_info.mode_config_initialized = false;
- return 0;
-}
-
-static int dce_virtual_hw_init(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-
- switch (adev->asic_type) {
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_TAHITI:
- case CHIP_PITCAIRN:
- case CHIP_VERDE:
- case CHIP_OLAND:
- dce_v6_0_disable_dce(adev);
- break;
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
- case CHIP_BONAIRE:
- case CHIP_HAWAII:
- case CHIP_KAVERI:
- case CHIP_KABINI:
- case CHIP_MULLINS:
- dce_v8_0_disable_dce(adev);
- break;
-#endif
- case CHIP_FIJI:
- case CHIP_TONGA:
- dce_v10_0_disable_dce(adev);
- break;
- case CHIP_CARRIZO:
- case CHIP_STONEY:
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_VEGAM:
- dce_v11_0_disable_dce(adev);
- break;
- case CHIP_TOPAZ:
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_HAINAN:
-#endif
- /* no DCE */
- break;
- default:
- break;
- }
- return 0;
-}
-
-static int dce_virtual_hw_fini(void *handle)
-{
- return 0;
-}
-
-static int dce_virtual_suspend(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int r;
-
- r = drm_mode_config_helper_suspend(adev_to_drm(adev));
- if (r)
- return r;
- return dce_virtual_hw_fini(handle);
-}
-
-static int dce_virtual_resume(void *handle)
-{
- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int r;
-
- r = dce_virtual_hw_init(handle);
- if (r)
- return r;
- return drm_mode_config_helper_resume(adev_to_drm(adev));
-}
-
-static bool dce_virtual_is_idle(void *handle)
-{
- return true;
-}
-
-static int dce_virtual_wait_for_idle(void *handle)
-{
- return 0;
-}
-
-static int dce_virtual_soft_reset(void *handle)
-{
- return 0;
-}
-
-static int dce_virtual_set_clockgating_state(void *handle,
- enum amd_clockgating_state state)
-{
- return 0;
-}
-
-static int dce_virtual_set_powergating_state(void *handle,
- enum amd_powergating_state state)
-{
- return 0;
-}
-
-static const struct amd_ip_funcs dce_virtual_ip_funcs = {
- .name = "dce_virtual",
- .early_init = NULL,
- .late_init = NULL,
- .sw_init = dce_virtual_sw_init,
- .sw_fini = dce_virtual_sw_fini,
- .hw_init = dce_virtual_hw_init,
- .hw_fini = dce_virtual_hw_fini,
- .suspend = dce_virtual_suspend,
- .resume = dce_virtual_resume,
- .is_idle = dce_virtual_is_idle,
- .wait_for_idle = dce_virtual_wait_for_idle,
- .soft_reset = dce_virtual_soft_reset,
- .set_clockgating_state = dce_virtual_set_clockgating_state,
- .set_powergating_state = dce_virtual_set_powergating_state,
-};
-
-const struct amdgpu_ip_block_version dce_virtual_ip_block =
-{
- .type = AMD_IP_BLOCK_TYPE_DCE,
- .major = 1,
- .minor = 0,
- .rev = 0,
- .funcs = &dce_virtual_ip_funcs,
-};
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
deleted file mode 100644
index ed422012c8c6..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef __DCE_VIRTUAL_H__
-#define __DCE_VIRTUAL_H__
-
-extern const struct amdgpu_ip_block_version dce_virtual_ip_block;
-
-#endif
-
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index 436fb13e32f0..ff80786e3918 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -58,7 +58,7 @@
#include "jpeg_v2_0.h"
#include "vcn_v3_0.h"
#include "jpeg_v3_0.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "mes_v10_1.h"
#include "mxgpu_nv.h"
#include "smuio_v11_0.h"
@@ -721,7 +721,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
!amdgpu_sriov_vf(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -749,7 +749,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -779,7 +779,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
is_support_sw_smu(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -802,7 +802,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
is_support_sw_smu(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -823,7 +823,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -843,7 +843,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
is_support_sw_smu(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -865,7 +865,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -883,11 +883,11 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -905,7 +905,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
}
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 7cbc2bb03bc6..e6d2f74a7976 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -44,7 +44,7 @@
#include "dce_v6_0.h"
#include "si.h"
#include "uvd_v3_1.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "gca/gfx_6_0_d.h"
#include "oss/oss_1_0_d.h"
#include "oss/oss_1_0_sh_mask.h"
@@ -2759,7 +2759,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2777,7 +2777,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2795,7 +2795,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
break;
default:
BUG();
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index a5e085e570f7..f7b56a746c15 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -74,7 +74,7 @@
#include "smuio_v9_0.h"
#include "smuio_v11_0.h"
#include "smuio_v13_0.h"
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "mxgpu_ai.h"
#include "amdgpu_ras.h"
#include "amdgpu_xgmi.h"
@@ -843,7 +843,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
}
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -863,7 +863,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -885,7 +885,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
}
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
@@ -909,7 +909,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 3d21c0799037..fe9a7cc8d9eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -77,7 +77,7 @@
#if defined(CONFIG_DRM_AMD_ACP)
#include "amdgpu_acp.h"
#endif
-#include "dce_virtual.h"
+#include "amdgpu_vkms.h"
#include "mxgpu_vi.h"
#include "amdgpu_dm.h"
@@ -2102,7 +2102,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v2_4_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
break;
case CHIP_FIJI:
amdgpu_device_ip_block_add(adev, &vi_common_ip_block);
@@ -2112,7 +2112,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2132,7 +2132,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2155,7 +2155,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_1_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2173,7 +2173,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
@@ -2194,7 +2194,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
if (adev->enable_virtual_display)
- amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+ amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
#if defined(CONFIG_DRM_AMD_DC)
else if (amdgpu_device_has_dc_support(adev))
amdgpu_device_ip_block_add(adev, &dm_ip_block);
--
2.32.0
^ permalink raw reply related [flat|nested] 13+ messages in thread