Commit bb1278e8 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-fixes-2018-04-25' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

sun41: Fix regression for TBSA711 tablet (Ondrej)
qxl: 2 bug fixes (Gerd)
core: Don't use stale display info between HDMI hotplugs (Ville)
virtio: Fix guest spinning when request queue is full (Gerd)

Cc: Ondrej Jirman <megous@megous.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>

* tag 'drm-misc-fixes-2018-04-25' of git://anongit.freedesktop.org/drm/drm-misc:
  drm/edid: Reset more of the display info
  drm/virtio: fix vq wait_event condition
  qxl: keep separate release_bo pointer
  qxl: fix qxl_release_{map,unmap}
  Revert "drm/sun4i: add lvds mode_valid function"
parents 14cdea89 1f6b8eef
...@@ -4451,6 +4451,7 @@ drm_reset_display_info(struct drm_connector *connector) ...@@ -4451,6 +4451,7 @@ drm_reset_display_info(struct drm_connector *connector)
info->max_tmds_clock = 0; info->max_tmds_clock = 0;
info->dvi_dual = false; info->dvi_dual = false;
info->has_hdmi_infoframe = false; info->has_hdmi_infoframe = false;
memset(&info->hdmi, 0, sizeof(info->hdmi));
info->non_desktop = 0; info->non_desktop = 0;
} }
...@@ -4462,17 +4463,11 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi ...@@ -4462,17 +4463,11 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
u32 quirks = edid_get_quirks(edid); u32 quirks = edid_get_quirks(edid);
drm_reset_display_info(connector);
info->width_mm = edid->width_cm * 10; info->width_mm = edid->width_cm * 10;
info->height_mm = edid->height_cm * 10; info->height_mm = edid->height_cm * 10;
/* driver figures it out in this case */
info->bpc = 0;
info->color_formats = 0;
info->cea_rev = 0;
info->max_tmds_clock = 0;
info->dvi_dual = false;
info->has_hdmi_infoframe = false;
info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP); info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop); DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
......
...@@ -179,10 +179,9 @@ qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *relea ...@@ -179,10 +179,9 @@ qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *relea
uint32_t type, bool interruptible) uint32_t type, bool interruptible)
{ {
struct qxl_command cmd; struct qxl_command cmd;
struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
cmd.type = type; cmd.type = type;
cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset); cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset);
return qxl_ring_push(qdev->command_ring, &cmd, interruptible); return qxl_ring_push(qdev->command_ring, &cmd, interruptible);
} }
...@@ -192,10 +191,9 @@ qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *releas ...@@ -192,10 +191,9 @@ qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *releas
uint32_t type, bool interruptible) uint32_t type, bool interruptible)
{ {
struct qxl_command cmd; struct qxl_command cmd;
struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
cmd.type = type; cmd.type = type;
cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset); cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset);
return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible); return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible);
} }
......
...@@ -167,6 +167,7 @@ struct qxl_release { ...@@ -167,6 +167,7 @@ struct qxl_release {
int id; int id;
int type; int type;
struct qxl_bo *release_bo;
uint32_t release_offset; uint32_t release_offset;
uint32_t surface_release_id; uint32_t surface_release_id;
struct ww_acquire_ctx ticket; struct ww_acquire_ctx ticket;
......
...@@ -182,9 +182,9 @@ static int qxl_process_single_command(struct qxl_device *qdev, ...@@ -182,9 +182,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
goto out_free_reloc; goto out_free_reloc;
/* TODO copy slow path code from i915 */ /* TODO copy slow path code from i915 */
fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE)); fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK));
unwritten = __copy_from_user_inatomic_nocache unwritten = __copy_from_user_inatomic_nocache
(fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE), (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK),
u64_to_user_ptr(cmd->command), cmd->command_size); u64_to_user_ptr(cmd->command), cmd->command_size);
{ {
......
...@@ -173,6 +173,7 @@ qxl_release_free_list(struct qxl_release *release) ...@@ -173,6 +173,7 @@ qxl_release_free_list(struct qxl_release *release)
list_del(&entry->tv.head); list_del(&entry->tv.head);
kfree(entry); kfree(entry);
} }
release->release_bo = NULL;
} }
void void
...@@ -296,7 +297,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev, ...@@ -296,7 +297,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
{ {
if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) { if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
int idr_ret; int idr_ret;
struct qxl_bo_list *entry = list_first_entry(&create_rel->bos, struct qxl_bo_list, tv.head);
struct qxl_bo *bo; struct qxl_bo *bo;
union qxl_release_info *info; union qxl_release_info *info;
...@@ -304,8 +304,9 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev, ...@@ -304,8 +304,9 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release); idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
if (idr_ret < 0) if (idr_ret < 0)
return idr_ret; return idr_ret;
bo = to_qxl_bo(entry->tv.bo); bo = create_rel->release_bo;
(*release)->release_bo = bo;
(*release)->release_offset = create_rel->release_offset + 64; (*release)->release_offset = create_rel->release_offset + 64;
qxl_release_list_add(*release, bo); qxl_release_list_add(*release, bo);
...@@ -365,6 +366,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, ...@@ -365,6 +366,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]); bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);
(*release)->release_bo = bo;
(*release)->release_offset = qdev->current_release_bo_offset[cur_idx] * release_size_per_bo[cur_idx]; (*release)->release_offset = qdev->current_release_bo_offset[cur_idx] * release_size_per_bo[cur_idx];
qdev->current_release_bo_offset[cur_idx]++; qdev->current_release_bo_offset[cur_idx]++;
...@@ -408,13 +410,12 @@ union qxl_release_info *qxl_release_map(struct qxl_device *qdev, ...@@ -408,13 +410,12 @@ union qxl_release_info *qxl_release_map(struct qxl_device *qdev,
{ {
void *ptr; void *ptr;
union qxl_release_info *info; union qxl_release_info *info;
struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); struct qxl_bo *bo = release->release_bo;
struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_SIZE); ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_MASK);
if (!ptr) if (!ptr)
return NULL; return NULL;
info = ptr + (release->release_offset & ~PAGE_SIZE); info = ptr + (release->release_offset & ~PAGE_MASK);
return info; return info;
} }
...@@ -422,11 +423,10 @@ void qxl_release_unmap(struct qxl_device *qdev, ...@@ -422,11 +423,10 @@ void qxl_release_unmap(struct qxl_device *qdev,
struct qxl_release *release, struct qxl_release *release,
union qxl_release_info *info) union qxl_release_info *info)
{ {
struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); struct qxl_bo *bo = release->release_bo;
struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
void *ptr; void *ptr;
ptr = ((void *)info) - (release->release_offset & ~PAGE_SIZE); ptr = ((void *)info) - (release->release_offset & ~PAGE_MASK);
qxl_bo_kunmap_atomic_page(qdev, bo, ptr); qxl_bo_kunmap_atomic_page(qdev, bo, ptr);
} }
......
...@@ -94,64 +94,9 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder) ...@@ -94,64 +94,9 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
} }
} }
static enum drm_mode_status sun4i_lvds_encoder_mode_valid(struct drm_encoder *crtc,
const struct drm_display_mode *mode)
{
struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(crtc);
struct sun4i_tcon *tcon = lvds->tcon;
u32 hsync = mode->hsync_end - mode->hsync_start;
u32 vsync = mode->vsync_end - mode->vsync_start;
unsigned long rate = mode->clock * 1000;
long rounded_rate;
DRM_DEBUG_DRIVER("Validating modes...\n");
if (hsync < 1)
return MODE_HSYNC_NARROW;
if (hsync > 0x3ff)
return MODE_HSYNC_WIDE;
if ((mode->hdisplay < 1) || (mode->htotal < 1))
return MODE_H_ILLEGAL;
if ((mode->hdisplay > 0x7ff) || (mode->htotal > 0xfff))
return MODE_BAD_HVALUE;
DRM_DEBUG_DRIVER("Horizontal parameters OK\n");
if (vsync < 1)
return MODE_VSYNC_NARROW;
if (vsync > 0x3ff)
return MODE_VSYNC_WIDE;
if ((mode->vdisplay < 1) || (mode->vtotal < 1))
return MODE_V_ILLEGAL;
if ((mode->vdisplay > 0x7ff) || (mode->vtotal > 0xfff))
return MODE_BAD_VVALUE;
DRM_DEBUG_DRIVER("Vertical parameters OK\n");
tcon->dclk_min_div = 7;
tcon->dclk_max_div = 7;
rounded_rate = clk_round_rate(tcon->dclk, rate);
if (rounded_rate < rate)
return MODE_CLOCK_LOW;
if (rounded_rate > rate)
return MODE_CLOCK_HIGH;
DRM_DEBUG_DRIVER("Clock rate OK\n");
return MODE_OK;
}
static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = { static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
.disable = sun4i_lvds_encoder_disable, .disable = sun4i_lvds_encoder_disable,
.enable = sun4i_lvds_encoder_enable, .enable = sun4i_lvds_encoder_enable,
.mode_valid = sun4i_lvds_encoder_mode_valid,
}; };
static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = { static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
......
...@@ -293,7 +293,7 @@ static int virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev, ...@@ -293,7 +293,7 @@ static int virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev,
ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC); ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC);
if (ret == -ENOSPC) { if (ret == -ENOSPC) {
spin_unlock(&vgdev->ctrlq.qlock); spin_unlock(&vgdev->ctrlq.qlock);
wait_event(vgdev->ctrlq.ack_queue, vq->num_free); wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt);
spin_lock(&vgdev->ctrlq.qlock); spin_lock(&vgdev->ctrlq.qlock);
goto retry; goto retry;
} else { } else {
...@@ -368,7 +368,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev, ...@@ -368,7 +368,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev,
ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC); ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC);
if (ret == -ENOSPC) { if (ret == -ENOSPC) {
spin_unlock(&vgdev->cursorq.qlock); spin_unlock(&vgdev->cursorq.qlock);
wait_event(vgdev->cursorq.ack_queue, vq->num_free); wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt);
spin_lock(&vgdev->cursorq.qlock); spin_lock(&vgdev->cursorq.qlock);
goto retry; goto retry;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment