提交 443fbd5f 编写于 作者: O Oded Gabbay

drm/amdkfd: Encapsulate KQ functions in ops structure

This patch does some re-org on the kernel_queue structure. It takes out
all the function pointers from the structure and puts them in a new structure,
called kernel_queue_ops. Then, it puts an instance of that structure
inside kernel_queue.

This re-org is done to prepare the KQ module to support more than one AMD APU
(Kaveri).
Signed-off-by: NOded Gabbay <oded.gabbay@amd.com>
Reviewed-by: NAlex Deucher <alexander.deucher@amd.com>
上级 a22fc854
...@@ -293,14 +293,14 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, ...@@ -293,14 +293,14 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
if (!kq) if (!kq)
return NULL; return NULL;
kq->initialize = initialize; kq->ops.initialize = initialize;
kq->uninitialize = uninitialize; kq->ops.uninitialize = uninitialize;
kq->acquire_packet_buffer = acquire_packet_buffer; kq->ops.acquire_packet_buffer = acquire_packet_buffer;
kq->submit_packet = submit_packet; kq->ops.submit_packet = submit_packet;
kq->sync_with_hw = sync_with_hw; kq->ops.sync_with_hw = sync_with_hw;
kq->rollback_packet = rollback_packet; kq->ops.rollback_packet = rollback_packet;
if (kq->initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) { if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
pr_err("kfd: failed to init kernel queue\n"); pr_err("kfd: failed to init kernel queue\n");
kfree(kq); kfree(kq);
return NULL; return NULL;
...@@ -312,7 +312,7 @@ void kernel_queue_uninit(struct kernel_queue *kq) ...@@ -312,7 +312,7 @@ void kernel_queue_uninit(struct kernel_queue *kq)
{ {
BUG_ON(!kq); BUG_ON(!kq);
kq->uninitialize(kq); kq->ops.uninitialize(kq);
kfree(kq); kfree(kq);
} }
...@@ -329,12 +329,12 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) ...@@ -329,12 +329,12 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
BUG_ON(!kq); BUG_ON(!kq);
retval = kq->acquire_packet_buffer(kq, 5, &buffer); retval = kq->ops.acquire_packet_buffer(kq, 5, &buffer);
BUG_ON(retval != 0); BUG_ON(retval != 0);
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
buffer[i] = kq->nop_packet; buffer[i] = kq->nop_packet;
kq->submit_packet(kq); kq->ops.submit_packet(kq);
kq->sync_with_hw(kq, 1000); kq->ops.sync_with_hw(kq, 1000);
pr_debug("kfd: ending kernel queue test\n"); pr_debug("kfd: ending kernel queue test\n");
} }
......
...@@ -28,8 +28,31 @@ ...@@ -28,8 +28,31 @@
#include <linux/types.h> #include <linux/types.h>
#include "kfd_priv.h" #include "kfd_priv.h"
struct kernel_queue { /**
/* interface */ * struct kernel_queue_ops
*
* @initialize: Initialize a kernel queue, including allocations of GART memory
* needed for the queue.
*
* @uninitialize: Uninitialize a kernel queue and free all its memory usages.
*
* @acquire_packet_buffer: Returns a pointer to the location in the kernel
* queue ring buffer where the calling function can write its packet. It is
* Guaranteed that there is enough space for that packet. It also updates the
* pending write pointer to that location so subsequent calls to
* acquire_packet_buffer will get a correct write pointer
*
* @submit_packet: Update the write pointer and doorbell of a kernel queue.
*
* @sync_with_hw: Wait until the write pointer and the read pointer of a kernel
* queue are equal, which means the CP has read all the submitted packets.
*
* @rollback_packet: This routine is called if we failed to build an acquired
* packet for some reason. It just overwrites the pending wptr with the current
* one
*
*/
struct kernel_queue_ops {
bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev, bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev,
enum kfd_queue_type type, unsigned int queue_size); enum kfd_queue_type type, unsigned int queue_size);
void (*uninitialize)(struct kernel_queue *kq); void (*uninitialize)(struct kernel_queue *kq);
...@@ -41,6 +64,10 @@ struct kernel_queue { ...@@ -41,6 +64,10 @@ struct kernel_queue {
int (*sync_with_hw)(struct kernel_queue *kq, int (*sync_with_hw)(struct kernel_queue *kq,
unsigned long timeout_ms); unsigned long timeout_ms);
void (*rollback_packet)(struct kernel_queue *kq); void (*rollback_packet)(struct kernel_queue *kq);
};
struct kernel_queue {
struct kernel_queue_ops ops;
/* data */ /* data */
struct kfd_dev *dev; struct kfd_dev *dev;
......
...@@ -348,7 +348,7 @@ int pm_send_set_resources(struct packet_manager *pm, ...@@ -348,7 +348,7 @@ int pm_send_set_resources(struct packet_manager *pm,
pr_debug("kfd: In func %s\n", __func__); pr_debug("kfd: In func %s\n", __func__);
mutex_lock(&pm->lock); mutex_lock(&pm->lock);
pm->priv_queue->acquire_packet_buffer(pm->priv_queue, pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
sizeof(*packet) / sizeof(uint32_t), sizeof(*packet) / sizeof(uint32_t),
(unsigned int **)&packet); (unsigned int **)&packet);
if (packet == NULL) { if (packet == NULL) {
...@@ -375,8 +375,8 @@ int pm_send_set_resources(struct packet_manager *pm, ...@@ -375,8 +375,8 @@ int pm_send_set_resources(struct packet_manager *pm,
packet->queue_mask_lo = lower_32_bits(res->queue_mask); packet->queue_mask_lo = lower_32_bits(res->queue_mask);
packet->queue_mask_hi = upper_32_bits(res->queue_mask); packet->queue_mask_hi = upper_32_bits(res->queue_mask);
pm->priv_queue->submit_packet(pm->priv_queue); pm->priv_queue->ops.submit_packet(pm->priv_queue);
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
mutex_unlock(&pm->lock); mutex_unlock(&pm->lock);
...@@ -402,7 +402,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues) ...@@ -402,7 +402,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t); packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
mutex_lock(&pm->lock); mutex_lock(&pm->lock);
retval = pm->priv_queue->acquire_packet_buffer(pm->priv_queue, retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
packet_size_dwords, &rl_buffer); packet_size_dwords, &rl_buffer);
if (retval != 0) if (retval != 0)
goto fail_acquire_packet_buffer; goto fail_acquire_packet_buffer;
...@@ -412,15 +412,15 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues) ...@@ -412,15 +412,15 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
if (retval != 0) if (retval != 0)
goto fail_create_runlist; goto fail_create_runlist;
pm->priv_queue->submit_packet(pm->priv_queue); pm->priv_queue->ops.submit_packet(pm->priv_queue);
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
mutex_unlock(&pm->lock); mutex_unlock(&pm->lock);
return retval; return retval;
fail_create_runlist: fail_create_runlist:
pm->priv_queue->rollback_packet(pm->priv_queue); pm->priv_queue->ops.rollback_packet(pm->priv_queue);
fail_acquire_packet_buffer: fail_acquire_packet_buffer:
mutex_unlock(&pm->lock); mutex_unlock(&pm->lock);
fail_create_runlist_ib: fail_create_runlist_ib:
...@@ -438,7 +438,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, ...@@ -438,7 +438,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
BUG_ON(!pm || !fence_address); BUG_ON(!pm || !fence_address);
mutex_lock(&pm->lock); mutex_lock(&pm->lock);
retval = pm->priv_queue->acquire_packet_buffer( retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue, pm->priv_queue,
sizeof(struct pm4_query_status) / sizeof(uint32_t), sizeof(struct pm4_query_status) / sizeof(uint32_t),
(unsigned int **)&packet); (unsigned int **)&packet);
...@@ -459,8 +459,8 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, ...@@ -459,8 +459,8 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
packet->data_hi = upper_32_bits((uint64_t)fence_value); packet->data_hi = upper_32_bits((uint64_t)fence_value);
packet->data_lo = lower_32_bits((uint64_t)fence_value); packet->data_lo = lower_32_bits((uint64_t)fence_value);
pm->priv_queue->submit_packet(pm->priv_queue); pm->priv_queue->ops.submit_packet(pm->priv_queue);
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
mutex_unlock(&pm->lock); mutex_unlock(&pm->lock);
return 0; return 0;
...@@ -482,7 +482,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, ...@@ -482,7 +482,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
BUG_ON(!pm); BUG_ON(!pm);
mutex_lock(&pm->lock); mutex_lock(&pm->lock);
retval = pm->priv_queue->acquire_packet_buffer( retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue, pm->priv_queue,
sizeof(struct pm4_unmap_queues) / sizeof(uint32_t), sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
&buffer); &buffer);
...@@ -537,8 +537,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, ...@@ -537,8 +537,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
break; break;
}; };
pm->priv_queue->submit_packet(pm->priv_queue); pm->priv_queue->ops.submit_packet(pm->priv_queue);
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
mutex_unlock(&pm->lock); mutex_unlock(&pm->lock);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册