Commit 2ec6bd67 authored by Gerd Hoffmann's avatar Gerd Hoffmann

drm/qxl: simplify slot management

Drop pointless indirection, remove the mem_slots array and index
variables, drop dynamic allocation.  Store memslots in qxl_device
instead.
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Acked-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20190118122020.27596-4-kraxel@redhat.com
parent d934ef6b
...@@ -130,9 +130,11 @@ struct qxl_mman { ...@@ -130,9 +130,11 @@ struct qxl_mman {
}; };
struct qxl_memslot { struct qxl_memslot {
int index;
const char *name;
uint8_t generation; uint8_t generation;
uint64_t start_phys_addr; uint64_t start_phys_addr;
uint64_t end_phys_addr; uint64_t size;
uint64_t high_bits; uint64_t high_bits;
}; };
...@@ -228,11 +230,8 @@ struct qxl_device { ...@@ -228,11 +230,8 @@ struct qxl_device {
unsigned int primary_created:1; unsigned int primary_created:1;
struct qxl_memslot *mem_slots; struct qxl_memslot main_slot;
uint8_t n_mem_slots; struct qxl_memslot surfaces_slot;
uint8_t main_mem_slot;
uint8_t surfaces_mem_slot;
uint8_t slot_id_bits; uint8_t slot_id_bits;
uint8_t slot_gen_bits; uint8_t slot_gen_bits;
uint64_t va_slot_mask; uint64_t va_slot_mask;
...@@ -312,8 +311,8 @@ static inline uint64_t ...@@ -312,8 +311,8 @@ static inline uint64_t
qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo, qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
unsigned long offset) unsigned long offset)
{ {
int slot_id = bo->type == QXL_GEM_DOMAIN_VRAM ? qdev->main_mem_slot : qdev->surfaces_mem_slot; struct qxl_memslot *slot = bo->type == QXL_GEM_DOMAIN_VRAM
struct qxl_memslot *slot = &(qdev->mem_slots[slot_id]); ? &qdev->main_slot : &qdev->surfaces_slot;
/* TODO - need to hold one of the locks to read tbo.offset */ /* TODO - need to hold one of the locks to read tbo.offset */
return slot->high_bits | (bo->tbo.offset + offset); return slot->high_bits | (bo->tbo.offset + offset);
......
...@@ -53,40 +53,46 @@ static bool qxl_check_device(struct qxl_device *qdev) ...@@ -53,40 +53,46 @@ static bool qxl_check_device(struct qxl_device *qdev)
return true; return true;
} }
static void setup_hw_slot(struct qxl_device *qdev, int slot_index, static void setup_hw_slot(struct qxl_device *qdev, struct qxl_memslot *slot)
struct qxl_memslot *slot)
{ {
qdev->ram_header->mem_slot.mem_start = slot->start_phys_addr; qdev->ram_header->mem_slot.mem_start = slot->start_phys_addr;
qdev->ram_header->mem_slot.mem_end = slot->end_phys_addr; qdev->ram_header->mem_slot.mem_end = slot->start_phys_addr + slot->size;
qxl_io_memslot_add(qdev, slot_index); qxl_io_memslot_add(qdev, qdev->rom->slots_start + slot->index);
} }
static uint8_t setup_slot(struct qxl_device *qdev, uint8_t slot_index_offset, static void setup_slot(struct qxl_device *qdev,
unsigned long start_phys_addr, unsigned long end_phys_addr) struct qxl_memslot *slot,
unsigned int slot_index,
const char *slot_name,
unsigned long start_phys_addr,
unsigned long size)
{ {
uint64_t high_bits; uint64_t high_bits;
struct qxl_memslot *slot;
uint8_t slot_index;
slot_index = qdev->rom->slots_start + slot_index_offset; slot->index = slot_index;
slot = &qdev->mem_slots[slot_index]; slot->name = slot_name;
slot->start_phys_addr = start_phys_addr; slot->start_phys_addr = start_phys_addr;
slot->end_phys_addr = end_phys_addr; slot->size = size;
setup_hw_slot(qdev, slot_index, slot); setup_hw_slot(qdev, slot);
slot->generation = qdev->rom->slot_generation; slot->generation = qdev->rom->slot_generation;
high_bits = slot_index << qdev->slot_gen_bits; high_bits = (qdev->rom->slots_start + slot->index)
<< qdev->slot_gen_bits;
high_bits |= slot->generation; high_bits |= slot->generation;
high_bits <<= (64 - (qdev->slot_gen_bits + qdev->slot_id_bits)); high_bits <<= (64 - (qdev->slot_gen_bits + qdev->slot_id_bits));
slot->high_bits = high_bits; slot->high_bits = high_bits;
return slot_index;
DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n",
slot->index, slot->name,
(unsigned long)slot->start_phys_addr,
(unsigned long)slot->size);
} }
void qxl_reinit_memslots(struct qxl_device *qdev) void qxl_reinit_memslots(struct qxl_device *qdev)
{ {
setup_hw_slot(qdev, qdev->main_mem_slot, &qdev->mem_slots[qdev->main_mem_slot]); setup_hw_slot(qdev, &qdev->main_slot);
setup_hw_slot(qdev, qdev->surfaces_mem_slot, &qdev->mem_slots[qdev->surfaces_mem_slot]); setup_hw_slot(qdev, &qdev->surfaces_slot);
} }
static void qxl_gc_work(struct work_struct *work) static void qxl_gc_work(struct work_struct *work)
...@@ -231,22 +237,11 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -231,22 +237,11 @@ int qxl_device_init(struct qxl_device *qdev,
} }
/* TODO - slot initialization should happen on reset. where is our /* TODO - slot initialization should happen on reset. where is our
* reset handler? */ * reset handler? */
qdev->n_mem_slots = qdev->rom->slots_end;
qdev->slot_gen_bits = qdev->rom->slot_gen_bits; qdev->slot_gen_bits = qdev->rom->slot_gen_bits;
qdev->slot_id_bits = qdev->rom->slot_id_bits; qdev->slot_id_bits = qdev->rom->slot_id_bits;
qdev->va_slot_mask = qdev->va_slot_mask =
(~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits); (~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits);
qdev->mem_slots =
kmalloc_array(qdev->n_mem_slots, sizeof(struct qxl_memslot),
GFP_KERNEL);
if (!qdev->mem_slots) {
DRM_ERROR("Unable to alloc mem slots\n");
r = -ENOMEM;
goto release_ring_free;
}
idr_init(&qdev->release_idr); idr_init(&qdev->release_idr);
spin_lock_init(&qdev->release_idr_lock); spin_lock_init(&qdev->release_idr_lock);
spin_lock_init(&qdev->release_lock); spin_lock_init(&qdev->release_lock);
...@@ -264,24 +259,17 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -264,24 +259,17 @@ int qxl_device_init(struct qxl_device *qdev,
r = qxl_irq_init(qdev); r = qxl_irq_init(qdev);
if (r) { if (r) {
DRM_ERROR("Unable to init qxl irq\n"); DRM_ERROR("Unable to init qxl irq\n");
goto mem_slots_free; goto release_ring_free;
} }
/* /*
* Note that virtual is surface0. We rely on the single ioremap done * Note that virtual is surface0. We rely on the single ioremap done
* before. * before.
*/ */
qdev->main_mem_slot = setup_slot(qdev, 0, setup_slot(qdev, &qdev->main_slot, 0, "main",
(unsigned long)qdev->vram_base, (unsigned long)qdev->vram_base,
(unsigned long)qdev->vram_base + qdev->rom->ram_header_offset); (unsigned long)qdev->rom->ram_header_offset);
qdev->surfaces_mem_slot = setup_slot(qdev, 1, setup_slot(qdev, &qdev->surfaces_slot, 1, "surfaces",
(unsigned long)qdev->surfaceram_base,
(unsigned long)qdev->surfaceram_base + qdev->surfaceram_size);
DRM_INFO("main mem slot %d [%lx,%x]\n",
qdev->main_mem_slot,
(unsigned long)qdev->vram_base, qdev->rom->ram_header_offset);
DRM_INFO("surface mem slot %d [%lx,%lx]\n",
qdev->surfaces_mem_slot,
(unsigned long)qdev->surfaceram_base, (unsigned long)qdev->surfaceram_base,
(unsigned long)qdev->surfaceram_size); (unsigned long)qdev->surfaceram_size);
...@@ -289,8 +277,6 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -289,8 +277,6 @@ int qxl_device_init(struct qxl_device *qdev,
return 0; return 0;
mem_slots_free:
kfree(qdev->mem_slots);
release_ring_free: release_ring_free:
qxl_ring_free(qdev->release_ring); qxl_ring_free(qdev->release_ring);
cursor_ring_free: cursor_ring_free:
......
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