summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vkms
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/vkms')
-rw-r--r--drivers/gpu/drm/vkms/Makefile1
-rw-r--r--drivers/gpu/drm/vkms/vkms_crc.c9
-rw-r--r--drivers/gpu/drm/vkms/vkms_crtc.c56
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.h10
-rw-r--r--drivers/gpu/drm/vkms/vkms_output.c10
-rw-r--r--drivers/gpu/drm/vkms/vkms_plane.c8
6 files changed, 50 insertions, 44 deletions
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 37966914f70b..89f09bec7b23 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
vkms-y := vkms_drv.o vkms_plane.o vkms_output.o vkms_crtc.o vkms_gem.o vkms_crc.o
obj-$(CONFIG_DRM_VKMS) += vkms.o
diff --git a/drivers/gpu/drm/vkms/vkms_crc.c b/drivers/gpu/drm/vkms/vkms_crc.c
index d7b409a3c0f8..e66ff25c008e 100644
--- a/drivers/gpu/drm/vkms/vkms_crc.c
+++ b/drivers/gpu/drm/vkms/vkms_crc.c
@@ -212,6 +212,15 @@ out:
spin_unlock_irqrestore(&out->state_lock, flags);
}
+static const char * const pipe_crc_sources[] = {"auto"};
+
+const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
+ size_t *count)
+{
+ *count = ARRAY_SIZE(pipe_crc_sources);
+ return pipe_crc_sources;
+}
+
static int vkms_crc_parse_source(const char *src_name, bool *enabled)
{
int ret = 0;
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index bb66dbcd5e3f..4d11292bc6f3 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -15,6 +15,10 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
spin_lock(&output->lock);
+ 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("vkms failure on handling vblank");
@@ -35,10 +39,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
DRM_WARN("failed to queue vkms_crc_work_handle");
}
- ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
- output->period_ns);
- WARN_ON(ret_overrun != 1);
-
spin_unlock(&output->lock);
return HRTIMER_RESTART;
@@ -74,33 +74,23 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
{
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
struct vkms_output *output = &vkmsdev->output;
+ struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
*vblank_time = output->vblank_hrtimer.node.expires;
- if (!in_vblank_irq)
- *vblank_time -= output->period_ns;
-
- return true;
-}
-
-static void vkms_atomic_crtc_reset(struct drm_crtc *crtc)
-{
- struct vkms_crtc_state *vkms_state = NULL;
+ if (WARN_ON(*vblank_time == vblank->time))
+ return true;
- if (crtc->state) {
- vkms_state = to_vkms_crtc_state(crtc->state);
- __drm_atomic_helper_crtc_destroy_state(crtc->state);
- kfree(vkms_state);
- crtc->state = NULL;
- }
-
- vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL);
- if (!vkms_state)
- return;
- INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle);
+ /*
+ * 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;
- crtc->state = &vkms_state->base;
- crtc->state->crtc = crtc;
+ return true;
}
static struct drm_crtc_state *
@@ -135,6 +125,19 @@ static void vkms_atomic_crtc_destroy_state(struct drm_crtc *crtc,
}
}
+static void vkms_atomic_crtc_reset(struct drm_crtc *crtc)
+{
+ struct vkms_crtc_state *vkms_state =
+ kzalloc(sizeof(*vkms_state), GFP_KERNEL);
+
+ if (crtc->state)
+ vkms_atomic_crtc_destroy_state(crtc, crtc->state);
+
+ __drm_atomic_helper_crtc_reset(crtc, &vkms_state->base);
+ if (vkms_state)
+ INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle);
+}
+
static const struct drm_crtc_funcs vkms_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = drm_crtc_cleanup,
@@ -144,6 +147,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
.atomic_destroy_state = vkms_atomic_crtc_destroy_state,
.enable_vblank = vkms_enable_vblank,
.disable_vblank = vkms_disable_vblank,
+ .get_crc_sources = vkms_get_crc_sources,
.set_crc_source = vkms_set_crc_source,
.verify_crc_source = vkms_verify_crc_source,
};
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 81f1cfbeb936..b92c30c66a6f 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -20,14 +20,6 @@
extern bool enable_cursor;
-static const u32 vkms_formats[] = {
- DRM_FORMAT_XRGB8888,
-};
-
-static const u32 vkms_cursor_formats[] = {
- DRM_FORMAT_ARGB8888,
-};
-
struct vkms_crc_data {
struct drm_framebuffer fb;
struct drm_rect src, dst;
@@ -136,6 +128,8 @@ int vkms_gem_vmap(struct drm_gem_object *obj);
void vkms_gem_vunmap(struct drm_gem_object *obj);
/* CRC Support */
+const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
+ size_t *count);
int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name);
int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
size_t *values_cnt);
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 3b162b25312e..56fb5c2a2315 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -6,7 +6,6 @@
static void vkms_connector_destroy(struct drm_connector *connector)
{
- drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -71,12 +70,6 @@ int vkms_output_init(struct vkms_device *vkmsdev)
drm_connector_helper_add(connector, &vkms_conn_helper_funcs);
- ret = drm_connector_register(connector);
- if (ret) {
- DRM_ERROR("Failed to register connector\n");
- goto err_connector_register;
- }
-
ret = drm_encoder_init(dev, encoder, &vkms_encoder_funcs,
DRM_MODE_ENCODER_VIRTUAL, NULL);
if (ret) {
@@ -99,9 +92,6 @@ err_attach:
drm_encoder_cleanup(encoder);
err_encoder:
- drm_connector_unregister(connector);
-
-err_connector_register:
drm_connector_cleanup(connector);
err_connector:
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 0e67d2d42f0c..0fceb6258422 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -6,6 +6,14 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+static const u32 vkms_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+static const u32 vkms_cursor_formats[] = {
+ DRM_FORMAT_ARGB8888,
+};
+
static struct drm_plane_state *
vkms_plane_duplicate_state(struct drm_plane *plane)
{