Skip to content

Commit

Permalink
added ioctl fix from MDJ
Browse files Browse the repository at this point in the history
  • Loading branch information
LorDClockaN committed Jan 1, 2012
1 parent ab24552 commit 7d75f28
Show file tree
Hide file tree
Showing 15 changed files with 1,162 additions and 102 deletions.
6 changes: 3 additions & 3 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/Kconfig
Expand Up @@ -57,9 +57,9 @@ config MSM_KGSL_PSTMRTMDMP_RB_HEX
of the human readable version.

config MSM_KGSL_2D
bool "Enable the 2D core. Required for OpenVG"
default n
depends on MSM_KGSL && !ARCH_MSM7X27
tristate "MSM 2D graphics driver. Required for OpenVG"
default y
depends on MSM_KGSL && !ARCH_MSM7X27 && !ARCH_MSM7X27A && !(ARCH_QSD8X50 && !MSM_SOC_REV_A)

config MSM_KGSL_DRM
bool "Build a DRM interface for the MSM_KGSL driver"
Expand Down
9 changes: 2 additions & 7 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/Makefile
Expand Up @@ -14,18 +14,13 @@ msm_adreno-$(CONFIG_GPU_MSM_KGSL) += \
adreno_ringbuffer.o \
adreno_drawctxt.o \
adreno_postmortem.o \
adreno.o
adreno.o \

msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o

msm_z180-$(CONFIG_MSM_KGSL_2D) += \
kgsl_g12_drawctxt.o \
kgsl_g12_cmdstream.o \
kgsl_g12.o

msm_kgsl_core-objs = $(msm_kgsl_core-y)
msm_adreno-objs = $(msm_kgsl_adreno-y)
msm_z180-objs = $(msm_kgsl_z180-y)
msm_z180-objs = $(msm_z180-y)

obj-$(CONFIG_GPU_MSM_KGSL) += \
msm_kgsl_core.o \
Expand Down
68 changes: 21 additions & 47 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/adreno.c
Expand Up @@ -34,10 +34,6 @@
(RBBM_INT_CNTL__RDERR_INT_MASK | \
RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK)

#define GSL_SQ_INT_MASK \
(SQ_INT_CNTL__PS_WATCHDOG_MASK | \
SQ_INT_CNTL__VS_WATCHDOG_MASK)

/* Yamato MH arbiter config*/
#define KGSL_CFG_YAMATO_MHARB \
(0x10 \
Expand Down Expand Up @@ -191,25 +187,6 @@ static void kgsl_yamato_rbbm_intrcallback(struct kgsl_device *device)
kgsl_yamato_regwrite_isr(device, REG_RBBM_INT_ACK, status);
}

static void kgsl_yamato_sq_intrcallback(struct kgsl_device *device)
{
unsigned int status = 0;

kgsl_yamato_regread_isr(device, REG_SQ_INT_STATUS, &status);

if (status & SQ_INT_CNTL__PS_WATCHDOG_MASK)
KGSL_DRV_INFO(device, "sq ps watchdog interrupt\n");
else if (status & SQ_INT_CNTL__VS_WATCHDOG_MASK)
KGSL_DRV_INFO(device, "sq vs watchdog interrupt\n");
else
KGSL_DRV_WARN(device,
"bad bits in REG_SQ_INT_STATUS %08x\n", status);


status &= GSL_SQ_INT_MASK;
kgsl_yamato_regwrite_isr(device, REG_SQ_INT_ACK, status);
}

irqreturn_t kgsl_yamato_isr(int irq, void *data)
{
irqreturn_t result = IRQ_NONE;
Expand Down Expand Up @@ -239,19 +216,14 @@ irqreturn_t kgsl_yamato_isr(int irq, void *data)
result = IRQ_HANDLED;
}

if (status & MASTER_INT_SIGNAL__SQ_INT_STAT) {
kgsl_yamato_sq_intrcallback(device);
result = IRQ_HANDLED;
}

if (device->requested_state == KGSL_STATE_NONE) {
if (device->pwrctrl.nap_allowed == true) {
device->requested_state = KGSL_STATE_NAP;
queue_work(device->work_queue, &device->idle_check_ws);
} else if (device->pwrctrl.idle_pass == true) {
queue_work(device->work_queue, &device->idle_check_ws);
if (device->requested_state == KGSL_STATE_NONE) {
if (device->pwrctrl.nap_allowed == true) {
device->requested_state = KGSL_STATE_NAP;
queue_work(device->work_queue, &device->idle_check_ws);
} else if (device->pwrctrl.idle_pass == true) {
queue_work(device->work_queue, &device->idle_check_ws);
}
}
}

/* Reset the time-out in our idle timer */
mod_timer(&device->idle_timer,
Expand Down Expand Up @@ -628,8 +600,6 @@ static int kgsl_yamato_stop(struct kgsl_device *device)
del_timer(&device->idle_timer);
kgsl_yamato_regwrite(device, REG_RBBM_INT_CNTL, 0);

kgsl_yamato_regwrite(device, REG_SQ_INT_CNTL, 0);

yamato_device->drawctxt_active = NULL;

kgsl_ringbuffer_stop(&yamato_device->ringbuffer);
Expand Down Expand Up @@ -1044,7 +1014,10 @@ static void _yamato_regread(struct kgsl_device *device,
BUG_ON(offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes);
reg = (unsigned int *)(device->regspace.mmio_virt_base
+ (offsetwords << 2));
*value = readl(reg);
/*ensure this read finishes before the next one.
* i.e. act like normal readl() */
*value = __raw_readl(reg);
rmb();
}

void kgsl_yamato_regread(struct kgsl_device *device, unsigned int offsetwords,
Expand Down Expand Up @@ -1073,8 +1046,10 @@ static void _yamato_regwrite(struct kgsl_device *device,
reg = (unsigned int *)(device->regspace.mmio_virt_base
+ (offsetwords << 2));

writel(value, reg);

/*ensure previous writes post before this one,
* i.e. act like normal writel() */
wmb();
__raw_writel(value, reg);
}

void kgsl_yamato_regwrite(struct kgsl_device *device, unsigned int offsetwords,
Expand Down Expand Up @@ -1102,13 +1077,13 @@ static int kgsl_check_interrupt_timestamp(struct kgsl_device *device,
mutex_lock(&device->mutex);
kgsl_sharedmem_readl(&device->memstore, &enableflag,
KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable));
rmb();
mb();

if (enableflag) {
kgsl_sharedmem_readl(&device->memstore, &ref_ts,
KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts));
rmb();
if (timestamp_cmp(ref_ts, timestamp)) {
mb();
if (timestamp_cmp(ref_ts, timestamp) >= 0) {
kgsl_sharedmem_writel(&device->memstore,
KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
timestamp);
Expand Down Expand Up @@ -1158,9 +1133,7 @@ static int kgsl_yamato_waittimestamp(struct kgsl_device *device,
long status = 0;
struct kgsl_yamato_device *yamato_device = KGSL_YAMATO_DEVICE(device);

if (timestamp != yamato_device->ringbuffer.timestamp &&
timestamp_cmp(timestamp,
yamato_device->ringbuffer.timestamp)) {
if (timestamp_cmp(timestamp, yamato_device->ringbuffer.timestamp) > 0) {
KGSL_DRV_ERR(device, "Cannot wait for invalid ts: %x, "
"rb->timestamp: %x\n",
timestamp, yamato_device->ringbuffer.timestamp);
Expand Down Expand Up @@ -1215,7 +1188,8 @@ static unsigned int kgsl_yamato_readtimestamp(struct kgsl_device *device,
else if (type == KGSL_TIMESTAMP_RETIRED)
kgsl_sharedmem_readl(&device->memstore, &timestamp,
KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
rmb();
/* Make sure memory is synchronized before restarting the GPU */
mb();

return timestamp;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/video/msm/gpu/kgsl_adreno205_hc/adreno_debugfs.c
Expand Up @@ -218,7 +218,7 @@ static int kgsl_regread_nolock(struct kgsl_device *device,

reg = (unsigned int *)(device->regspace.mmio_virt_base
+ (offsetwords << 2));
*value = readl(reg);
*value = __raw_readl(reg);
return 0;
}

Expand Down
29 changes: 11 additions & 18 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/adreno_ringbuffer.c
Expand Up @@ -157,17 +157,10 @@ static void kgsl_ringbuffer_submit(struct kgsl_ringbuffer *rb)
{
BUG_ON(rb->wptr == 0);

GSL_RB_UPDATE_WPTR_POLLING(rb);
/* Drain write buffer and data memory barrier */
dsb();
wmb();

/* Memory fence to ensure all data has posted. On some systems,
* like 7x27, the register block is not allocated as strongly ordered
* memory. Adding a memory fence ensures ordering during ringbuffer
* submits.*/
/*synchronize memory before informing the hardware of the
*new commands.
*/
mb();
outer_sync();

kgsl_yamato_regwrite(rb->device, REG_CP_RB_WPTR, rb->wptr);

Expand Down Expand Up @@ -759,7 +752,7 @@ int kgsl_ringbuffer_extract(struct kgsl_ringbuffer *rb,

retired_timestamp = device->ftbl.device_readtimestamp(
device, KGSL_TIMESTAMP_RETIRED);
rmb();

KGSL_DRV_ERR(device, "GPU successfully executed till ts: %x\n",
retired_timestamp);
/*
Expand All @@ -776,7 +769,7 @@ int kgsl_ringbuffer_extract(struct kgsl_ringbuffer *rb,
* sucessfully executed command */
while ((rb_rptr / sizeof(unsigned int)) != rb->wptr) {
kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
rmb();

if (value == retired_timestamp) {
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
Expand All @@ -787,7 +780,7 @@ int kgsl_ringbuffer_extract(struct kgsl_ringbuffer *rb,
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
kgsl_sharedmem_readl(&rb->buffer_desc, &val3, rb_rptr);
rmb();

/* match the pattern found at the end of a command */
if ((val1 == 2 &&
val2 == pm4_type3_packet(PM4_INTERRUPT, 1)
Expand Down Expand Up @@ -834,7 +827,7 @@ int kgsl_ringbuffer_extract(struct kgsl_ringbuffer *rb,
kgsl_sharedmem_readl(&rb->buffer_desc, &val2,
adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size));
rmb();

if (val1 == pm4_nop_packet(1) && val2 == KGSL_CMD_IDENTIFIER) {
KGSL_DRV_ERR(device,
"GPU recovery from hang not possible because "
Expand All @@ -850,24 +843,24 @@ int kgsl_ringbuffer_extract(struct kgsl_ringbuffer *rb,
kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
rmb();

/* check for context switch indicator */
if (value == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
rmb();

BUG_ON(value != pm4_type3_packet(PM4_MEM_WRITE, 2));
kgsl_sharedmem_readl(&rb->buffer_desc, &val1, rb_rptr);
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
rmb();

BUG_ON(val1 != (device->memstore.gpuaddr +
KGSL_DEVICE_MEMSTORE_OFFSET(current_context)));
kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
rb->buffer_desc.size);
rmb();

BUG_ON((copy_rb_contents == 0) &&
(value == cur_context));
/* if context switches to a context that did not cause
Expand Down
15 changes: 3 additions & 12 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/adreno_ringbuffer.h
Expand Up @@ -101,11 +101,11 @@ struct kgsl_ringbuffer {

#define GSL_RB_WRITE(ring, gpuaddr, data) \
do { \
writel(data, ring); \
writel_relaxed(data, ring); \
wmb(); \
kgsl_cffdump_setmem(gpuaddr, data, 4); \
ring++; \
gpuaddr += sizeof(uint); \
wmb(); \
} while (0)

/* timestamp */
Expand All @@ -130,8 +130,7 @@ struct kgsl_ringbuffer {
#define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */
#define GSL_RB_GET_READPTR(rb, data) \
do { \
*(data) = readl(&(rb)->memptrs->rptr); \
rmb(); \
*(data) = readl_relaxed(&(rb)->memptrs->rptr); \
} while (0)
#else
#define GSL_RB_CNTL_NO_UPDATE 0x1 /* disable */
Expand All @@ -141,15 +140,7 @@ struct kgsl_ringbuffer {
} while (0)
#endif /* GSL_RB_USE_MEMRPTR */

/* wptr polling */
#ifdef GSL_RB_USE_WPTR_POLLING
#define GSL_RB_CNTL_POLL_EN 0x1 /* enable */
#define GSL_RB_UPDATE_WPTR_POLLING(rb) \
do { writel((rb)->wptr, &((rb)->memptrs->wptr_poll)); } while (0)
#else
#define GSL_RB_CNTL_POLL_EN 0x0 /* disable */
#define GSL_RB_UPDATE_WPTR_POLLING(rb)
#endif /* GSL_RB_USE_WPTR_POLLING */

int kgsl_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv,
struct kgsl_context *context,
Expand Down
18 changes: 15 additions & 3 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/kgsl.c
Expand Up @@ -258,7 +258,7 @@ static void kgsl_memqueue_drain(struct kgsl_device *device)
"ts_processed %d ts_free %d gpuaddr %x)\n",
ts_processed, entry->free_timestamp,
entry->memdesc.gpuaddr);
if (!timestamp_cmp(ts_processed, entry->free_timestamp))
if (timestamp_cmp(ts_processed, entry->free_timestamp) < 0)
break;

list_del(&entry->list);
Expand Down Expand Up @@ -353,7 +353,7 @@ int kgsl_check_timestamp(struct kgsl_device *device, unsigned int timestamp)
ts_processed = device->ftbl.device_readtimestamp(
device, KGSL_TIMESTAMP_RETIRED);

return timestamp_cmp(ts_processed, timestamp);
return (timestamp_cmp(ts_processed, timestamp) >= 0);
}
EXPORT_SYMBOL(kgsl_check_timestamp);

Expand Down Expand Up @@ -1767,7 +1767,7 @@ static const struct {
KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_USER_EVENT,
kgsl_ioctl_cff_user_event, 0),
KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
kgsl_ioctl_timestamp_event, 0),
kgsl_ioctl_timestamp_event, 1),
};

static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
Expand Down Expand Up @@ -1874,6 +1874,17 @@ kgsl_mmap_memstore(struct kgsl_device *device, struct vm_area_struct *vma)
return result;
}

/*
* kgsl_gpumem_vm_open is called whenever a vma region is copied or split.
* Increase the refcount to make sure that the accounting stays correct
*/

static void kgsl_gpumem_vm_open(struct vm_area_struct *vma)
{
struct kgsl_mem_entry *entry = vma->vm_private_data;
kgsl_mem_entry_get(entry);
}

static int
kgsl_gpumem_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
Expand All @@ -1893,6 +1904,7 @@ kgsl_gpumem_vm_close(struct vm_area_struct *vma)
}

static struct vm_operations_struct kgsl_gpumem_vm_ops = {
.open = kgsl_gpumem_vm_open,
.fault = kgsl_gpumem_vm_fault,
.close = kgsl_gpumem_vm_close,
};
Expand Down
8 changes: 6 additions & 2 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/kgsl.h
Expand Up @@ -252,10 +252,14 @@ static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
return NULL;
}

static inline bool timestamp_cmp(unsigned int new, unsigned int old)
static inline int timestamp_cmp(unsigned int new, unsigned int old)
{
int ts_diff = new - old;
return (ts_diff >= 0) || (ts_diff < -20000);

if (ts_diff == 0)
return 0;

return ((ts_diff > 0) || (ts_diff < -20000)) ? 1 : -1;
}

static inline void
Expand Down
6 changes: 3 additions & 3 deletions drivers/video/msm/gpu/kgsl_adreno205_hc/kgsl_cffdump.c
Expand Up @@ -435,7 +435,7 @@ void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
/* Ensure that this memory region is not read from the
* cache but fetched fresh */

dsb(); wmb(); mb();
mb();

kgsl_cache_range_op(memdesc->hostptr, memdesc->size,
memdesc->type, KGSL_CACHE_OP_INV);
Expand Down Expand Up @@ -608,8 +608,8 @@ bool kgsl_cffdump_parse_ibs(struct kgsl_device_private *dev_priv,
if (!memdesc->physaddr) {
KGSL_CORE_ERR("no physaddr");
return true;
else {
dsb(); wmb(); mb();
} else {
mb();
kgsl_cache_range_op(memdesc->hostptr, memdesc->size,
memdesc->type, KGSL_CACHE_OP_INV);
}
Expand Down

0 comments on commit 7d75f28

Please sign in to comment.