104 lines
2.9 KiB
C
104 lines
2.9 KiB
C
/*
|
|
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
|
*
|
|
* All source code in this file is licensed under the following license
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, you can find it at http://www.fsf.org
|
|
*/
|
|
|
|
#include "kgsl.h"
|
|
#include "kgsl_device.h"
|
|
#include "kgsl_cmdstream.h"
|
|
#include "kgsl_sharedmem.h"
|
|
|
|
int kgsl_cmdstream_init(struct kgsl_device *device)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int kgsl_cmdstream_close(struct kgsl_device *device)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
uint32_t
|
|
kgsl_cmdstream_readtimestamp(struct kgsl_device *device,
|
|
enum kgsl_timestamp_type type)
|
|
{
|
|
uint32_t timestamp = 0;
|
|
|
|
KGSL_CMD_VDBG("enter (device_id=%d, type=%d)\n", device->id, type);
|
|
|
|
if (type == KGSL_TIMESTAMP_CONSUMED)
|
|
KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device,
|
|
(unsigned int *)×tamp);
|
|
else if (type == KGSL_TIMESTAMP_RETIRED)
|
|
KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device,
|
|
(unsigned int *)×tamp);
|
|
|
|
KGSL_CMD_VDBG("return %d\n", timestamp);
|
|
|
|
return timestamp;
|
|
}
|
|
|
|
int kgsl_cmdstream_check_timestamp(struct kgsl_device *device,
|
|
unsigned int timestamp)
|
|
{
|
|
unsigned int ts_processed;
|
|
|
|
ts_processed = kgsl_cmdstream_readtimestamp(device,
|
|
KGSL_TIMESTAMP_RETIRED);
|
|
return timestamp_cmp(ts_processed, timestamp);
|
|
}
|
|
|
|
void kgsl_cmdstream_memqueue_drain(struct kgsl_device *device)
|
|
{
|
|
struct kgsl_mem_entry *entry, *entry_tmp;
|
|
uint32_t ts_processed;
|
|
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
|
|
|
/* get current EOP timestamp */
|
|
ts_processed =
|
|
kgsl_cmdstream_readtimestamp(device, KGSL_TIMESTAMP_RETIRED);
|
|
|
|
list_for_each_entry_safe(entry, entry_tmp, &rb->memqueue, free_list) {
|
|
/*NOTE: this assumes that the free list is sorted by
|
|
* timestamp, but I'm not yet sure that it is a valid
|
|
* assumption
|
|
*/
|
|
if (!timestamp_cmp(ts_processed, entry->free_timestamp))
|
|
break;
|
|
KGSL_MEM_DBG("ts_processed %d ts_free %d gpuaddr %x)\n",
|
|
ts_processed, entry->free_timestamp,
|
|
entry->memdesc.gpuaddr);
|
|
kgsl_remove_mem_entry(entry);
|
|
}
|
|
}
|
|
|
|
int
|
|
kgsl_cmdstream_freememontimestamp(struct kgsl_device *device,
|
|
struct kgsl_mem_entry *entry,
|
|
uint32_t timestamp,
|
|
enum kgsl_timestamp_type type)
|
|
{
|
|
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
|
KGSL_MEM_DBG("enter (dev %p gpuaddr %x ts %d)\n",
|
|
device, entry->memdesc.gpuaddr, timestamp);
|
|
(void)type; /* unref. For now just use EOP timestamp */
|
|
|
|
list_add_tail(&entry->free_list, &rb->memqueue);
|
|
entry->free_timestamp = timestamp;
|
|
|
|
return 0;
|
|
}
|