Exemple #1
0
static irqreturn_t z180_irq_handler(struct kgsl_device *device)
{
    irqreturn_t result = IRQ_NONE;
    unsigned int status;
    struct z180_device *z180_dev = Z180_DEVICE(device);

    z180_regread(device, ADDR_VGC_IRQSTATUS >> 2, &status);

    trace_kgsl_z180_irq_status(device, status);

    if (status & GSL_VGC_INT_MASK) {
        z180_regwrite(device,
                      ADDR_VGC_IRQSTATUS >> 2, status & GSL_VGC_INT_MASK);

        result = IRQ_HANDLED;

        if (status & REG_VGC_IRQSTATUS__FIFO_MASK)
            KGSL_DRV_ERR(device, "z180 fifo interrupt\n");
        if (status & REG_VGC_IRQSTATUS__MH_MASK)
            kgsl_mh_intrcallback(device);
        if (status & REG_VGC_IRQSTATUS__G2D_MASK) {
            int count;

            z180_regread(device,
                         ADDR_VGC_IRQ_ACTIVE_CNT >> 2,
                         &count);

            count >>= 8;
            count &= 255;
            z180_dev->timestamp += count;

            queue_work(device->work_queue, &device->ts_expired_ws);
            wake_up_interruptible(&device->wait_queue);
        }
static void z180_dump_ringbuffer(struct kgsl_device *device)
{
	unsigned int rb_size;
	unsigned int *rb_hostptr;
	unsigned int rb_words;
	unsigned int rb_gpuaddr;
	struct z180_device *z180_dev = Z180_DEVICE(device);
	unsigned int i;
	char linebuf[CHARS_PER_LINE];

	KGSL_LOG_DUMP(device, "Z180 ringbuffer dump\n");

	rb_hostptr = (unsigned int *) z180_dev->ringbuffer.cmdbufdesc.hostptr;

	rb_size = Z180_RB_SIZE;
	rb_gpuaddr = z180_dev->ringbuffer.cmdbufdesc.gpuaddr;

	rb_words = rb_size/sizeof(unsigned int);

	KGSL_LOG_DUMP(device, "ringbuffer size: %u\n", rb_size);

	KGSL_LOG_DUMP(device, "rb_words: %d\n", rb_words);

	for (i = 0; i < rb_words; i += WORDS_PER_LINE) {
		hex_dump_to_buffer(rb_hostptr+i,
				rb_size - i*sizeof(unsigned int),
				WORDS_PER_LINE*sizeof(unsigned int),
				sizeof(unsigned int), linebuf,
				sizeof(linebuf), false);
		KGSL_LOG_DUMP(device, "RB: %04X: %s\n",
				rb_gpuaddr + i*sizeof(unsigned int), linebuf);
	}
}
int z180_dump(struct kgsl_device *device, int manual)
{
	struct z180_device *z180_dev = Z180_DEVICE(device);

	mb();

	KGSL_LOG_DUMP(device, "Retired Timestamp: %d\n", z180_dev->timestamp);
	KGSL_LOG_DUMP(device,
			"Current Timestamp: %d\n", z180_dev->current_timestamp);

	
	z180_dump_ringbuffer(device);

	
	z180_dump_regs(device);

	
	if (device->pm_ib_enabled)
		z180_dump_ib(device);

	
	if (!manual)
		BUG_ON(1);

	return 0;
}
/**
 * z180_dump - Dumps the Z180 ringbuffer and registers (and IBs if asked for)
 * for postmortem
 * analysis.
 * @device: kgsl_device pointer to the Z180 core
 */
int z180_dump(struct kgsl_device *device, int manual)
{
	struct z180_device *z180_dev = Z180_DEVICE(device);

	mb();

	KGSL_LOG_DUMP(device, "Retired Timestamp: %d\n", z180_dev->timestamp);
	KGSL_LOG_DUMP(device,
			"Current Timestamp: %d\n", z180_dev->current_timestamp);

	/* Dump ringbuffer */
	z180_dump_ringbuffer(device);

	/* Dump registers */
	z180_dump_regs(device);

	/* Dump IBs, if asked for */
	if (device->pm_ib_enabled)
		z180_dump_ib(device);

	/* Get the stack trace if the dump was automatic */
	if (!manual)
		BUG_ON(1);

	return 0;
}
static irqreturn_t z180_isr(int irq, void *data)
{
	irqreturn_t result = IRQ_NONE;
	unsigned int status;
	struct kgsl_device *device = (struct kgsl_device *) data;
	struct z180_device *z180_dev = Z180_DEVICE(device);

	z180_regread(device, ADDR_VGC_IRQSTATUS >> 2, &status);

	if (status & GSL_VGC_INT_MASK) {
		z180_regwrite(device,
			ADDR_VGC_IRQSTATUS >> 2, status & GSL_VGC_INT_MASK);

		result = IRQ_HANDLED;

		if (status & REG_VGC_IRQSTATUS__FIFO_MASK)
			KGSL_DRV_ERR(device, "z180 fifo interrupt\n");
		if (status & REG_VGC_IRQSTATUS__MH_MASK)
			kgsl_mh_intrcallback(device);
		if (status & REG_VGC_IRQSTATUS__G2D_MASK) {
			int count;

			z180_regread(device,
					 ADDR_VGC_IRQ_ACTIVE_CNT >> 2,
					 &count);

			count >>= 8;
			count &= 255;
			z180_dev->timestamp += count;

			queue_work(device->work_queue, &device->ts_expired_ws);
			wake_up_interruptible(&device->wait_queue);

			atomic_notifier_call_chain(
				&(device->ts_notifier_list),
				device->id, NULL);
		}
static void z180_dump_ib(struct kgsl_device *device)
{
	unsigned int rb_size;
	unsigned int *rb_hostptr;
	unsigned int rb_words;
	unsigned int rb_gpuaddr;
	unsigned int ib_gpuptr = 0;
	unsigned int ib_size = 0;
	void *ib_hostptr = NULL;
	int rb_slot_num = -1;
	struct z180_device *z180_dev = Z180_DEVICE(device);
	struct kgsl_mem_entry *entry = NULL;
	phys_addr_t pt_base;
	unsigned int i;
	unsigned int j;
	char linebuf[CHARS_PER_LINE];
	unsigned int current_ib_slot;
	unsigned int len;
	unsigned int rowsize;
	KGSL_LOG_DUMP(device, "Z180 IB dump\n");

	rb_hostptr = (unsigned int *) z180_dev->ringbuffer.cmdbufdesc.hostptr;

	rb_size = Z180_RB_SIZE;
	rb_gpuaddr = z180_dev->ringbuffer.cmdbufdesc.gpuaddr;

	rb_words = rb_size/sizeof(unsigned int);

	KGSL_LOG_DUMP(device, "Ringbuffer size (bytes): %u\n", rb_size);

	KGSL_LOG_DUMP(device, "rb_words: %d\n", rb_words);

	pt_base = kgsl_mmu_get_current_ptbase(&device->mmu);

	
	for (i = 0; i < rb_words; i++) {
		if (rb_hostptr[i] == Z180_STREAM_PACKET_CALL) {

			rb_slot_num++;
			current_ib_slot =
				z180_dev->current_timestamp % Z180_PACKET_COUNT;
			if (rb_slot_num != current_ib_slot)
				continue;

			ib_gpuptr = rb_hostptr[i+1];

			entry = kgsl_get_mem_entry(device, pt_base, ib_gpuptr,
							1);

			if (entry == NULL) {
				KGSL_LOG_DUMP(device,
				"IB mem entry not found for ringbuffer slot#: %d\n",
				rb_slot_num);
				continue;
			}

			ib_hostptr = kgsl_memdesc_map(&entry->memdesc);

			if (ib_hostptr == NULL) {
				KGSL_LOG_DUMP(device,
				"Could not map IB to kernel memory, Ringbuffer Slot: %d\n",
				rb_slot_num);
				kgsl_mem_entry_put(entry);
				continue;
			}

			ib_size = entry->memdesc.size;
			KGSL_LOG_DUMP(device,
				"IB size: %dbytes, IB size in words: %d\n",
				ib_size,
				ib_size/sizeof(unsigned int));

			for (j = 0; j < ib_size; j += WORDS_PER_LINE) {
				len = ib_size - j*sizeof(unsigned int);
				rowsize = WORDS_PER_LINE*sizeof(unsigned int);
				hex_dump_to_buffer(ib_hostptr+j, len, rowsize,
						sizeof(unsigned int), linebuf,
						sizeof(linebuf), false);
				KGSL_LOG_DUMP(device, "IB%d: %04X: %s\n",
						rb_slot_num,
						(rb_gpuaddr +
						j*sizeof(unsigned int)),
						linebuf);
			}
			KGSL_LOG_DUMP(device, "IB Dump Finished\n");
			kgsl_mem_entry_put(entry);
		}
	}
}